[Question]
  [
You must write a program or function that takes a string of brackets and outputs whether or not that string is fully matched. Your program should print a [truthy or falsy](http://meta.codegolf.stackexchange.com/questions/2190/interpretation-of-truthy-falsey) value, and IO can be in any [reasonable format](http://meta.codegolf.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods).
# Rules and definitions:
* For the purpose of this challenge, a "bracket" is any of these characters: `()[]{}<>`.
* A pair of brackets is considered "matched" if the opening and closing brackets are in the right order and have no characters inside of them, such as
```
()
[]{}
```
Or if every subelement inside of it is also matched.
```
[()()()()]
{<[]>}
(()())
```
Subelements can also be nested several layers deep.
```
[(){<><>[()]}<>()]
<[{((()))}]>
```
* A string is considered "Fully matched" if and only if:
	1. Every single character is a bracket,
	2. Each pair of brackets has the correct opening and closing bracket and in the right order, and
	3. Each bracket is matched.
* You may assume the input will only contain [printable ASCII](https://en.wikipedia.org/wiki/ASCII#Printable_characters).
# Test IO
Here are some inputs that should return a truthy value:
```
()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]
```
And here are some outputs that should return a falsy value:
```
(               Has no closing ')'
}{              Wrong order
(<)>            Each pair contains only half of a matched element
(()()foobar)    Contains invalid characters
[({}<>)>        The last bracket should be ']' instead of '>'
(((()))         Has 4 opening brackets, but only 3 closing brackets.
```
As usual, this is code-golf, so standard loopholes apply, and shortest answer in bytes wins.
  
[Answer]
# [Brain-Flak](https://github.com/DJMcMayhem/Brain-Flak), ~~1101, 1085~~, 981 bytes
```
{(<(({}))((((()()()()()){}){}){})({}[{}]<(())>){((<{}{}>))}{}>{({}<>)(<>)}{}<(({
}))((((()()()()()){}){}){}())({}[{}]<(())>){((<{}{}>))}{}>{({}<>)({}[{}](<()>)){
{}{}(<(())>)}{}{<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))(((((()()()()()){}){})){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()(<>)}{}<(({}))(((((()()()()()){}){})(
)){}{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((()()()){}){}()){({}[()])}{})({}[{}]<(()
)>){((<{}{}>))}{}>{<({}()()<>)>()(<>)}{}<(({}))((((((()()()()()){})){}{}())){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{<>{{
}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((((()()()()()){}){}){}())){}{})({}[{}]<(())>
){((<{}{}>))}{}>{<({}()()()<>)>()(<>)}{}<(({}))((((((()()()()()){}){}){}())()){}
{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<{}>[()]){<>{{}}(<()>)<>{{}}(<()>)}{}}<>([]<>)({}<
(())>){((<{}{}>))}{}
```
[Try it online!](https://tio.run/##rZNBDsIgFESvM7PoDQgXaVjgwsRoXLj94ew4QDU11Uq1pYVfGCZvUnq4xdN1OF7iOWeDAyyRKBcfjZpqtxZHS0Eq0tMAZ8mSJ0tvWnWe0KPXdSeVXV5NIyxJaEWAaYNKc15TqfWYRFWyIFggsHh9YXAooDLzYI8ntrvulW@GUcbiCwb20qylfI1ZE6rsT7p71g/naQtRf97naf3N/6/McqxfcdI1wbxOdTfG0H6Vt1A5o7I7P4aYh3gH "Brain-Flak – Try It Online")
This is 980 bytes of source code, and `+1` for the `-a` flag allowing ASCII input (but decimal output)
This is an answer I've been wanting to write for a *very very* long time. At least 6 months. I waited to post this because I knew that answering this challenge would be extra hard in brain-flak. But it's worth it for one very important reason: The source code itself is a truthy input, which is the entire point of this language itself.
And as I wrote about [here](http://meta.codegolf.stackexchange.com/a/9957/31716), this question was what inspired me to write brain-flak. 
> 
> Shortly after I wrote Are the brackets fully matched?, it made me wonder how much information you can store with only matched brackets. One thing that stood out to me, was that even though you only have 4 "atoms" of sorts:
> 
> 
> 
> ```
> (){}[]<>
> 
> ```
> 
> you really have 8 units of information to convey, since each of these bracket types can be empty, or have other brackets in between, which are fundamentally different pieces of information. So, I decided to write a language that only allowed for matched brackets, and where empty brackets convey something different than brackets with other brackets inside of them.
> 
> 
> 
This answer took roughly two hours to write. I'll admit it's pretty poorly golfed, mostly because a lot of the code is repeated for each bracket type. But I'm mostly amazed that I was able to write an answer at all, especially given that Brain-Flak is
> 
> A minimalist esolang designed to be painful to use
> 
> 
> 
I'm going to attempt to golf it down later, but I wanted to get this out there anyway.
I have a detailed explanation, but it's about 6 thousand characters long, so I think it would not be wise to paste the entire thing into this answer. You can read through it [here](https://gist.github.com/DJMcMayhem/52453a771830a0dcd42323d39396ce54) if you want. I'll add a shorter explanation here.
The basic idea, is that we repeat the following steps for every character on the stack:
* We check each character to see if it matches any bracket. If it is an opening bracket, we push a number onto the other stack according to the following mapping:
```
( = 1
< = 2
[ = 3
{ = 4
```
* Then we check to see if it matches any closing bracket. If it does, we push the equivalent number onto the alternate stack, just like for opening brackets. *Then*, we check if the top two numbers are equal. If they are, the both get popped and the program continues as normal. If they are not, we clear both stacks (to stop the looping) and push a one onto the alternate stack. This is essentially a "break" statement.
* After checking the 8 bracket types, we push the value of this run through the loop. Since we zero out most of it, the only snippets that have any value are the conditionals when we compare against brackets. So if any bracket is matched, the whole loop has a value of 1. If none of them did, the whole loop has a value of 0. In this case, we will clear both stacks and push a 0 onto the alternate stack. Again, this is like a "break" statement.
After this main loop is running, the rest is fairly simple. We are on the (empty) main stack, and the alternate stack is empty (if the brackets were matched) or non-empty if they were not. So we run this:
```
#Toggle to the alternate stack
<>
#Push this stack-height onto main-stack
([]<>)
#Logical not
({}<(())>){((<{}{}>))}{}
```
This will push a 0 or a 1 onto the main-stack, and when the program ends it is implicitly printed.
---
* *Thanks to [@WheatWizard](https://codegolf.stackexchange.com/users/56656/wheat-wizard) for coming up with a good stack-clean "equals" and "logical not" snippet, and for regularly updating the [github wiki](https://github.com/DJMcMayhem/Brain-Flak/wiki) with useful examples.*
* *Thanks to [@ASCII-only](https://codegolf.stackexchange.com/users/39244/ascii-only) for writing an online [integer metagolfer](https://brain-flak.github.io/integer/) which helped immensely in writing this program*
---
*revisions*
* *Removed some push pop redundancy*
* *Changed my zero counter logic*
[Answer]
# [Brain-Flak](https://github.com/DJMcMayhem/Brain-Flak), ~~204~~ ~~196~~ 190 bytes
```
{({}<>)<>((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())(({<({}<>[({})])>[()]{()(<{}>)}{}<>}{}()<({}<>[({})]){(<{}({}())>)}{}<>>)){(<({}{}<>[{}]{}<>)>)}{}{<>{{}}}{}}<>((){[()]<>})
```
[Try it online!](https://tio.run/##1Y5BCsMwDAS/oz3kB0IfKT64h0Bo6KHXRW9PVyIp5AmVwZI1y3qfn7m9l3Wfr@OgMT3gYVW4Dpgwoe6Apn7Zb@eGgKqg0dvlUXBAHYNycWYgi@gy3EQsWrbAqZGdllq1ijk6WEN6kJmasoKC9YNc8ff5l/kF "Brain-Flak – Try It Online")
-8 bytes thanks to Wheat Wizard. -6 bytes thanks to Jo King.
### Explanation
This program stores the character codes of all current unclosed brackets on the second stack. The bracket pairs `<>`, `[]`, and `{}` each have character codes that differ by exactly 2, so there is no need to check for them specifically. The pair `()` only differs by 1, so we check for `(` specifically, and effectively decrement that byte (actually increment every other byte) before continuing.
```
# While there are bytes left to process
{
 # Move byte to second stack
 ({}<>)<>
 # Push 40, 0, 40, 60, 91, 123: (, then null, then all four opening brackets
 ((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())
 ((
   # For each opening bracket type:
   {
    # Evaluate as zero
    <
     # Compute difference between bracket type and input byte
     ({}<>[({})])
    >
    # Evaluate loop iteration as -1 if equal, 0 otherwise
    [()]{()(<{}>)}{}<>
   }
   # Remove the 0 that was inserted to terminate that loop
   {}
   # Add 1 to result
   ()
   # Evaluate rest of this expression as zero
   <
    # Determine whether the byte is open parenthesis
    ({}<>[({})])
    # If not:
    {
     # Add 1 to byte and break if
     (<{}({}())>)
    }{}
    # Return to main stack
    <>
   >
 # Push result twice (0 if matched an opening bracket, 1 otherwise)
 ))
 # If byte was not an opening bracket:
 {
  # Push zero to break out of if
  (<
    # Push (open bracket + 2 - byte) below that zero
    ({}{}<>[{}]{}<>)
  >)
 }{}
 # If byte was neither an opening bracket nor the appropriate closing bracket:
 {
  # Clear alternate stack and stay there to break out of main loop early
  <>{{}}
 }{}
# End of main loop
}
# If a prefix was invalid, the top of the other stack is the same nonzero value
# that made us break out in the first place. If the string was a valid prefix,
# the other stack contains every unclosed bracket.  If the string is balanced,
# there are none of these. Thus, the other stack is empty if the
# brackets are balanced, and has a nonzero value on top otherwise.
# Push 1 on other stack if empty, and 0 on current stack otherwise
<>((){[()]<>})
```
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), 19 bytes
Input is given in *quotes*. Code:
```
"[](){}<>"2÷)"":g2Q
```
Well crap, a *lot* of bugs and unimplemented features were found. Explanation:
```
"[](){}<>"           # Push this string
          2÷         # Split into pieces of two
            )        # Wrap it into an array (which should not be needed)
             ""      # Push an empty string
               :     # Infinite replacement
```
This is actually a tricky part. What this looks like in pseudocode is:
```
input().replace(['[]', '()', '{}', '<>'], "")
```
This is covered by this part from the [05AB1E code](https://github.com/Adriandmen/05AB1E/blob/master/05AB1E.py#L1498):
```
if type(b) is list:
    temp_string = temp_string_2 = str(a)
    while True:
        for R in b:
            temp_string = temp_string.replace(R, c)
        if temp_string == temp_string_2:
            break
        else:
            temp_string_2 = temp_string
    stack.append(temp_string)
```
As you can see, this is **infinite replacement** (done until the string doesn't change anymore). So, I don't have to worry about setting the replacement into a loop, since this is already builtin. After that:
```
                g    # Take the length of the final string
                 2Q  # Check if equal with 2 (which are the quotes at the end)
```
Uses **CP-1252** encoding. [Try it online!](http://05ab1e.tryitonline.net/#code=IltdKCl7fTw-IjLDtCIiOmcyUQ&input=J1soW117fSk8e1soKTwoKT5dfSgpPnt9XSc) (slightly modified because the above version is deprecated).
[Answer]
## JavaScript (ES6), ~~52~~ 50 bytes
```
f=s=>(t=s.replace(/\(\)|\[]|{}|<>/,''))==s?!s:f(t)
```
Repeatedly remove brackets until the result is the same as the original, then return false unless the string is now empty.
Edit: Saved 2 bytes thanks to @edc65.
[Answer]
## Python, 67 bytes
```
lambda s:eval("s"+".replace('%s','')"*4%([],(),{},'<>')*len(s))==''
```
Generates and evals an expression that looks like
```
s.replace('[]','').replace('()','').replace('{}','').replace('<>','').replace('[]','').replace('()','').replace('{}','').replace('<>','')
```
and checks if the result is empty.
Sp3000 saved 8 bytes by pointing out that `[],(),{}` can be subbed in without quotes because they're Python objects, and that two parens were unneeded.
[Answer]
# Retina, 20 bytes
```
+`\(\)|\[]|{}|<>
^$
```
[Try it online](http://retina.tryitonline.net/#code=K2BcKFwpfFxbXXx7fXw8PgoKTWBeJA&input=WygpKCkoKSgpXQ)
[Answer]
## CJam, ~~25~~ ~~24~~ ~~23~~ 21 bytes
*Thanks to Sp3000 for saving 2 bytes.*  
*Thanks to jimmy23013 for saving 2 bytes.*
```
q_,{()<>}a`$2/*{/s}/!
```
[Test suite.](http://cjam.aditsu.net/#code=qN%2F%7B%3AQ%7B%0A%0AQ_%2C%7B()%3C%3E%7Da%60%242%2F*%7B%2Fs%7D%2F!%0A%0A%7D%26%5DoNo%7D%2F&input=()%0A%5B%5D()%7B%7D%3C%3E%0A(((())))%0A(%7B%5B%3C%3E%5D%7D)%0A%5B%7B()%3C%3E()%7D%5B%5D%5D%0A%5B(%5B%5D%7B%7D)%3C%7B%5B()%3C()%3E%5D%7D()%3E%7B%7D%5D%0A%0A(%0A%7D%7B%0A(%3C)%3E%0A(()()foobar)%0A%5B(%7B%7D%3C%3E)%3E%0A(((())))
Works essentially the same as the other answers: we repeatedly remove `()`, `[]`, `<>` and `{}` from the string and check if we end up with the empty string. To avoid having to check when we're done, we remove the pairs `N` times where `N` is the length of the string, which is always sufficient (since each iteration will remove at least two characters, unless we're done). I'm glad to see that this doesn't beat Retina. :) (Although Pyth or Jelly might...)
There's one fun golfing trick here: to get the string `()<>[]{}` we use the following:
```
{()<>}a`$
```
The, `{()<>}` is just a block (i.e. a function), which contains the other brackets as code. With `a` we wrap the block in an array. The ``` stringifies that array, which gives `"[{()<>}]"`. Finally, we sort the string with `$`, which rearranges the brackets to `()<>[]{}`.
[Answer]
# Yacc, 119 bytes
Does not use regex/replace.
```
%%input:r;r:%empty|'['r']'r|'{'r'}'r|'('r')'r|'<'r'>'r;%%yylex(){return getchar();}main(){return yyparse();}yyerror(){}
```
## Ungolfed
```
%%                              # Grammar in BNF
input:
  r;
r:
  %empty
| '['r']'r
| '{'r'}'r
| '('r')'r
| '<'r'>'r;
%%                              # Minimal parser invocation and lexer
yylex(){return getchar();}
main(){return yyparse();}
yyerror(){}
```
## Compilation
```
yacc -o bracket.c bracket.y
cc -o bracket bracket.c
```
## Usage
```
~/ % echo -n "<()[]>" | ./bracket
~/ %
~/ % echo -n "{" | ./bracket
~/ 1 %                                                                         :(
```
[Answer]
## Pyth, ~~31~~ ~~25~~ 24 bytes
Golfed down to 25 bytes thanks to FryAmTheEggMan
Removed 1 byte
```
VQ=:Q"<>|\[]|{}|\(\)"k;!
```
Try it here: [Test suite](https://pyth.herokuapp.com/?code=Vz%3D%3Az%22%3C%3E%7C%5C%5B%5D%7C%7B%7D%7C%5C%28%5C%29%22k%3B%21z&test_suite=1&test_suite_input=%28%29%0A%5B%5D%28%29%7B%7D%3C%3E%0A%28%28%28%28%29%29%29%29%0A%28%7B%5B%3C%3E%5D%7D%29%0A%5B%7B%28%29%3C%3E%28%29%7D%5B%5D%5D%0A%5B%28%5B%5D%7B%7D%29%3C%7B%5B%28%29%3C%28%29%3E%5D%7D%28%29%3E%7B%7D%5D%0A%28%0A%7D%7B%0A%28%3C%29%3E%0A%28%28%29%28%29foobar%29%0A%5B%28%7B%7D%3C%3E%29%3E%0A%28%28%28%28%29%29%29&debug=0) !
I'm still a Pyth newbie, any help is appreciated.
## Explanation
```
VQ                         For N in range(0, len(z)), with Q being the evaluated input.
                           Optimal solution would be to use range(0, len(z)/2) instead, but it add two bytes.
  =:Q"<>|\[]|{}|\(\)"k     assign Q without {}, [], <> nor () (regex replacement) to Q
                      ;    End of For loop
                       !   Logical NOT of Q's length (Q is the input, but has gone several times through y, and Q is implicit).
                           This last operation returns True if len(Q) is 0 (which means all brackets were matched), False otherwise
```
BTW, congrats to the other Pyth answer (which is currently 20 bytes)
[Answer]
# Pyth, 20 bytes
```
!uuscNTc"[](){}<>"2G
```
Try it online: [Test Suite](http://pyth.herokuapp.com/?code=!uuscNTc%22[]%28%29%7B%7D%3C%3E%222G&input=%22%28[%29]%22&test_suite=1&test_suite_input=%22%28%29%22%0A%22[]%28%29%7B%7D%3C%3E%22%0A%22%28%28%28%28%29%29%29%29%22%0A%22%28%7B[%3C%3E]%7D%29%22%0A%22[%7B%28%29%3C%3E%28%29%7D[]]%22%0A%22[%28[]%7B%7D%29%3C%7B[%28%29%3C%28%29%3E]%7D%28%29%3E%7B%7D]%22%0A%22%28%22%0A%22%7D%7B%22%0A%22%28%3C%29%3E%22%0A%22%28%28%29%28%29foobar%29%22%0A%22[%28%7B%7D%3C%3E%29%3E%22%0A%22%28%28%28%28%29%29%29%22&debug=0)
Repeatedly removes occurrences of `[]`, `()`, `<>` and `{}` by splitting and re-merging. Checks if the resulting string is empty or not. 
[Answer]
# Javascript ES6, 54 bytes
```
f=_=>_.match(x=/\(\)|\[]|{}|<>/)?f(_.replace(x,'')):!_
```
Uses a recursive replace implementation. Simple enough.
[Answer]
# [Brain-Flak](https://github.com/DJMcMayhem/Brain-Flak), 204 bytes
```
(()){{}{({}<>)<>}<>({<(<(({})<>)>)(((((((([(())()()()]){}){}){}())(()))(((())()){}()){})){})(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))<>{}<>{{}({}[({})]<>({})){(<>)(<>)}{}{}(<>)}{}>{}<>}<>)}{}((){<>[()]})
```
[Try it online!](https://tio.run/##3U9BDsMgDPuOfegPonyk6oEdKlWbdtg1yts7G/aKAUbBdgw8PuN6b@drPO8bIKu6UB3JSO2oQECEjkziN3ZbMedBiXOZEqbJ6qIkGXDSDK7e3cUEyxWiOtmW2mY7BDXbKebwM5wCvcGQTeoqprlXrWsr0pnNP/vNNr4 "Brain-Flak – Try It Online")
Not quite as short as [Nitroden's answer](https://codegolf.stackexchange.com/a/142224/76162), but uses a very different approach. This one runs through the input repeatedly, removing neighbouring matching pairs of brackets each time until there are none left. At that point if there is anything left on the stack, then the string was not fully matched.
### Explanation:
```
(())  Push 1 to simulate the check at the start of the loop
{  While check
	{}           Pop check
	{({}<>)<>}<> Reverse input
	({           Loop over input
		< Don't push the values of these calculations
		(<(({})<>)>)  Create a copy of the top of the input and push to the other stack
		(((((
		((([(())()()()]){}){}){}())
		(()))
		(((())()){}()){})
		){})          Push the differences in values of the end brackets 
		(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))  If the copy is the same as any of these, push the difference between the other bracket twice
		<>{}<>  Pop copy
		{  If this character is a start bracket
			{}({}[({})]<>({}))  Check if the next character is the end bracket
			{(<>)(<>)}{}          If not, push a 0 to each stack as buffer
			{}       Pop the top of the input stack, either the start bracket if they matched or the buffer 0
			(<>)     Push 0 to other stack to end check
		}{}>
		{}   Pop the top of the other stack
		         If the character was not an end bracket, pop the copy of check, which is 0
		         If it was, but didn't match the next character, pop the buffer 0
		         If the brackets matched, pop the end bracket and add it to the loop total
	<>}	Repeat with the rest of the input
	<>)	Push the loop total
		If any brackets were matched, the loop total is non zero
}{}
((){<>[()]}) If there is anything left on the stack, push 0 to the other stack, otherwise push 1
```
[Answer]
# Regex (PCRE flavor), ~~41~~ 37 bytes
```
^((<(?1)>|{(?1)}|\[(?1)]|\((?1)\))*)$
```
Just a standard solution with recursive regex.
*Thanks jimmy23013 for shaving off 4 bytes*
[Answer]
## Brainfuck, 132 bytes
```
+>,[[<->>+>[-]<<-]<[>+>[<+<+>>>+<-]+++++[>--------<-]>[<<+>++++[>-----<-]>[<++++
+[>------<-]>-[<++++[>--------<-]>[,>]]]]<],]<<[>]>.
```
Formatted:
```
+>,
[
  [<-> >+>[-]<<-]
  <
  [
    not matching closing bracket
    >+>[<+<+>> >+<-]
    +++++[>--------<-]
    >
    [
      not open paren
      <<+>
      ++++[>-----<-]>
      [
        not open angle bracket
        <+++++[>------<-]>-
        [
          not open square bracket
          <++++[>--------<-]>
          [
            not open brace
            ,>
          ]
        ]
      ]
    ]
    <
  ]
  ,
]
<<[>]
>.
```
Expects input without a trailing newline. Prints `\x00` for false and `\x01` for true.
[Try it online.](http://brainfuck.tryitonline.net/#code=Kz4sW1s8LT4-KzwtXTxbPis-PlstXTxbPCs8Kz4-Pis8LV0rKysrK1s-LS0tLS0tLS08LV0-Wzw8Kz4rKysrWz4tLS0tLTwtXT5bPCsrKysrWz4tLS0tLS08LV0-LVs8KysrK1s-LS0tLS0tLS08LV0-Wyw-XV1dXTxdLF08PFs-XT4u&input=WyhbXXt9KTx7WygpPCgpPl19KCk-e31d)
Approach: Maintain a stack starting with `\x01`, and push the corresponding closing bracket whenever an opening bracket is encountered. Before checking whether the current character is an opening bracket, first check whether it's equal to the closing bracket at the top of the stack, and if so pop it. If it's neither the proper closing bracket nor an opening bracket, consume the rest of the input while moving the pointer to the right. At the end, check whether the pointer is next to the initial `\x01`.
[Answer]
# Perl, ~~34~~ 33 bytes
Includes +2 for `-lp`
Run with input on STDIN:
```
./brackets.pl <<< "{<>()}"
```
`brackets.pl`:
```
#!/usr/bin/perl -lp
s/\(\)|\[]|<>|{}//&&redo;$_=!$_
```
Finds the first bracket pair without anything between them and removes it as long as there are any. Then checks if the final string is empty.
[Answer]
# Java 7, ~~156~~ 151 bytes
```
class A{public static void main(String[]a){for(int i=0;i<-1>>>1;++i,a[0]=a[0].replaceAll("<>|\\[]|\\(\\)|\\{}",""));System.out.print(a[0].isEmpty());}}
```
I'm not expecting this to win any awards but I didn't see a Java answer yet. Additionally, I like to lurk around PPCG and I would enjoy being able to vote/comment on other answers.
Input is given as program parameters. This follows the same format as many other answers here in that it preforms a regex replacement in a loop. Originally I had it loop N times where N is the length of the original string but looping to `Integer.MAX_VALUE` is shorter :]. This should be ok because `Integer.MAX_VALUE` is the maximum length of a `String` in Java so there's an implicit assumption that the length of input is something that is handle-able by Java. The runtime is pretty bad (took about 20 minutes on my lappytop) on account of the loop but I didn't see any restriction on that.
[Answer]
# [Haskell](https://www.haskell.org/), 151 bytes
```
infix 1#
'(':x#y=x#')':y
'<':x#y=x#'>':y
'[':x#y=x#']':y
'{':x#y=x#'}':y
')':x#')':y=x#y
'>':x#'>':y=x#y
']':x#']':y=x#y
'}':x#'}':y=x#y
""#""=1
_#_=0
```
[Try it online!](https://tio.run/##PcuxCsMgFIXh3acoWlDHrkEd@wTd5BIcLJXaUJIWDHKf3ZoLdTnwHfgfYXvGnFtLyz2V00UwqeRUxG6LkFpOO5Nm2JH9MJDrMJL1YWr71@3IbhjIMIxk/Jtzwbm9rd/IZjHba8hbZO0V0mLfa1o@Z@6Vh4raVK@0UdoB9qkIR9h@ "Haskell – Try It Online")
[Answer]
## [Grime](https://github.com/iatorm/grime/tree/v0.1) v0.1, 34 bytes
```
M=\(M\)|\[M\]|\{M\}|\<M\>|MM|_
e`M
```
Prints `1` for a match and `0` for no match.
[Try it online!](http://grime.tryitonline.net/#code=TT1cKE1cKXxcW01cXXxce01cfXxcPE1cPnxNTXxfCmVgTQ&input=WyhbXXt9KTx7WygpPCgpPl19KCk-e31d)
## Explanation
Grime is my 2D pattern-matching language designed for [this challenge](https://codegolf.stackexchange.com/questions/47311/language-design-2-d-pattern-matching); it can also be used to match 1D strings.
This is my first answer with it.
I did modify Grime today, but only to change the character of one syntax element (``` instead of `,`), so it doesn't affect my score.
```
M=                         Define pattern called M that matches:
\(M\)|\[M\]|\{M\}|\<M\>      a smaller M inside matched brackets,
|MM                          or two smaller Ms concatenated,
|_                           or the empty pattern.
e`M                        Match the entire input against M.
```
[Answer]
# Reng v.3.3, 137 bytes, noncompeting
[Try it here!](https://jsfiddle.net/Conor_OBrien/avnLdwtq/)
```
aií0#zl2,q!~1ø
:"]"eq!v:"}"eq!v:">"eq!v:")"eq!v)1z+#z
ve¤[2-2<       <       <     +1<
>]?v$$$zÀ0#z >ðq!vlqv¤l2%[1Ø
   \$2+)1z+#z/   ~n1/
```
There's a bit more golfing to be done, but at least it works. I added a command `ð` to keep track of stacks after this challenge in order for this to be remotely possible/easily. I'll explain this in a bit, but it generally keeps track of all strings iterated over and looks for repeats; if there is a repeat, then the string is irreducible. Otherwise, the string will be reduced to the empty string/stack, and will output `1`. Otherwise, no output will be produced.
[Answer]
## PowerShell v2+, ~~63~~ 62 bytes
```
param($a)for(;$a-ne$b){$a=($b=$a)-replace"\[\]|\(\)|<>|{}"}!$a
```
Can't quite catch JavaScript, but is currently edging out the other non-esolangs.
Similar approach as other answers: a simple loop that continues so long as we can remove one of `[]`, `()`, or `<>` (with several extraneous characters because we need to escape the regex specials). We use `$b` as a helper along the way to remember what our previous loop's `$a` was set as. An uninitialized variable is `$null`, so the first time the loop is encountered, `$a` is obviously not equal to `$null`.
At the end of the loop, `$a` is either empty or not, and the Boolean-not of that string is either `True` or `False`.
### Example
```
PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({})]"
True
PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({])}"
False
```
[Answer]
# C, ~~121~~ ~~122~~ 114 bytes
Shaved of 8 bytes thanks to @xsot!  
```
a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!k*!i);}
```
Uses a stack.
[Answer]
### Python 2.7, 96 bytes
```
def r(s):i=max(map(s.find,['()','[]','{}','<>']));return not len(s)if i<0 else r(s[:i]+s[i+2:])
```
[Answer]
# Julia, 51 bytes
```
~z=z==(n=replace(z,r"\(\)|\[]|{}|<>",""))?z=="":~n
```
The least insane of several options. Unsurprisingly, leveraging the power of regex is the shortest path to string matching, but this really only applies if the pattern to match is regular. Trying to do PCRE recursive patterns ends up ballooning the size of the code, either by seeing if the whole string is the match or by anchoring the ends and then creating a construct to specify the inner body for regex recursion. Neither of which are pretty or conducive to code golf. 
## Explanation:
```
~z=                            # Define ~z to be the following:
    z==(                       # If z is equal to                                     
        n=replace(z,           # z with the replacement of 
            r"\(\)|\[]|{}|<>", # adjacent matching brackets ((),[],{}, or <>)
            ""                 # with empty strings
        )                      # (which is assigned to n)
    )?z==""                    # whether z is an empty string
    :~n                        # else ~ applied to the substituted string
```
The function repeatedly removes adjacent pairs of parentheses from its only argument, and returns true if it can derive an empty string this way. 
[Answer]
# R, 298
```
function(.){s=strsplit;u=paste0;.=s(.,"")[[1]];p=s("><)(}{][","")[[1]];.[!.%in%p]="§";for(i in 1:4*2){.[.==p[i]]=sprintf("S('%s',{",p[i]);.[.==p[i-1]]=sprintf("},'%s');",p[i])};S=function(H,B,T)if(H!=T)stop();r=try(eval(parse(,,u(.,collapse=""))),1);if(inherits(r,"try-error"))FALSE else TRUE}
```
The approach here is to convert the sequence into R code, and then try to parse and evaluate it. If that gives an error, then return `FALSE`.
But there is a minor problem ... R's rules for brackets are different, so `<` and `>` are not brackets at all, and the other types have rules of their own. This is solved by a revolutionary approach -- a squeaking function, whose only function is to signal an error if its head and tail squeak in different ways.
For example, `[]` is transformed into `S('[', {}, ']')`, where S is defined as ...
```
S=function(H,B,T)if(H!=T)stop() 
```
Because the head squeak and tail squeak match, no error is thrown.
A few other examples (the left part is a sequence of brackets and right part is its transformation into valid R code that can be evaluated):
```
[}     -->  S('[', {}, '}')     # squeaks an error
[()]   -->  S('[', {S('(',{},'(')}, "[")
({[]}) -->  S('(',{S('{',{S('[',{},'[');},'{');},'(');
```
Some other sequences of brackets will result in parse errors:
```
[[)    -->   S('[',{S('[',{},'('); 
```
So the remaining part just catches the errors and returns FALSE if there are any, and TRUE if there are none.
The human-readble code: 
```
 sqk <- function(.){
   s=strsplit;u=paste0
   .=s(.,"")[[1]]            # break the argument up into 1-character pieces
   p=s("><)(}{][","")[[1]]   # vector of brackets
   .[!.%in%p]="§"            # replace anything besides brackets by § (--> error)
   for(i in 1:4*2){     
     .[.==p[i]]=sprintf("S('%s',{",p[i])    # '<' -->   S('<',{     ... etc
     .[.==p[i-1]]=sprintf("},'%s');",p[i])  # '>' -->   },'<');     ... etc  
   }
   S=function(H,B,T)if(H!=T)stop()          # define the working horse
   r=try(eval(parse(,,u(.,collapse=""))),1) # evaluate the sequence
   if(inherits(r,"try-error"))FALSE else TRUE   # any errors?
   }
```
Applying it on sample cases:
```
truthy<-readLines(textConnection("()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]"))
falsy<-readLines(textConnection("(
}
(<2)>
(()()foobar)
[({}<>)>
(((()))"))
> sapply(truthy,sqk)
                      ()                 [](){}<>                 (((()))) 
                    TRUE                     TRUE                     TRUE 
                ({[<>]})             [{()<>()}[]] [([]{})<{[()<()>]}()>{}] 
                    TRUE                     TRUE                     TRUE 
> sapply(falsy,sqk)
           (            }        (<2)> (()()foobar)     [({}<>)>      (((())) 
       FALSE        FALSE        FALSE        FALSE        FALSE        FALSE 
```
[Answer]
# Lua (92 bytes)
The older Lua answer is everything but golfing code. There's my proposal instead:
```
function x(s)m=""return s:gsub("%b<>",m):gsub("%b[]",m):gsub("%b{}",m):gsub("%b()",m)==m end
```
[Answer]
# [Stax](https://github.com/tomtheisen/stax), ~~11~~ 10 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
é:råvm∟&1Γ
```
[Run and debug it](https://staxlang.xyz/#p=823a7286766d1c2631e2&i=%28%29%0A%5B%5D%28%29%7B%7D%3C%3E%0A%28%28%28%28%29%29%29%29%0A%28%7B%5B%3C%3E%5D%7D%29%0A%5B%7B%28%29%3C%3E%28%29%7D%5B%5D%5D%0A%5B%28%5B%5D%7B%7D%29%3C%7B%5B%28%29%3C%28%29%3E%5D%7D%28%29%3E%7B%7D%5D%0A%28%0A%7D%7B%0A%28%3C%29%3E%0A%28%28%29%28%29foobar%29%0A%5B%28%7B%7D%3C%3E%29%3E%0A%28%28%28%28%29%29%29&a=1&m=2)
Got lucky, as stax has a literal constant in it with matched pairs of brackets.
[Answer]
# Curry, ~~64~~ 56 bytes
*Tested to work in both [PAKCS](https://www.informatik.uni-kiel.de/%7Epakcs/) and [KiCS2](https://www-ps.informatik.uni-kiel.de/kics2/)*
```
f(x:a++y:b)|elem[x,y]["{}","<>","[]","()"]=f a*f b
f""=1
```
[Try it on Smap!](https://smap.informatik.uni-kiel.de/smap.cgi?browser/80)
[Try it online!](https://tio.run/##HcixCoMwEADQ3a84jg5JtYWuIcneSfeQIdocSFUkVjCk@fZUurzhDXsI8ba697CVQuwQrq6j6PnXT342RxOtwZSxQalPjD1hHK0icFeCviJE9SizGxcQArrgp/3l788WGK/@q2AN4/KBCxAgM9akLLWVmqXMOZYf)
This returns `1` if string is balanced and nothing otherwise.
## Explanation
Our definition of `f` then matches the empty string as balanced for a base case:
```
f""=1
```
Then we have the main logic:
```
f(x:a++y:b)|[x,y]=:=anyOf["{}","<>","[]","()"]=f a*f b
```
Here `*` is used like a logical and. Since the only value we can get back is `1`, this always gives back `1` when it finds results. But when it doesn't this doesn't give any result.
With that this pattern matches strings with a pair of matching brackets so that they divide the input into two balanced strings.
[Answer]
# C, 258 bytes
```
#define E else if(a==
#define D(v) {if (b[--p]!=v)z=1;}
#define F b[p++]=
main(a, v) char* v[]; {char b[99],p=0,z=0;for(;*v[1];v[1]++) {a=*v[1];if(a=='(')F 0;E '[')F 1;E '{')F 2;E '<')F 3;E '>')D(3)E '}')D(2)E ']')D(1)E ')')D(0)else z=1;}puts(z|p?"0":"1");}
```
## Degolfed, macro-substituted, commented
```
int main(int a, char* v[]) {
//           ^ this variable is used as a general purpose int variable and not as its intended purpose (argc)
    char b[99], // create a 99 byte array for storing bracket types
        p = 0, // pointer within the array
        z = 0; // error flag
    // loop through every byte of input (argv[1])
    for(;*v[1];v[1]++) {
        a=*v[1];// a is the current byte
        if(a=='(') b[p++] = 0; // record bracket type
        else if(a== '[') b[p++] = 1;
        else if(a== '{') b[p++] = 2;
        else if(a== '<') b[p++] = 3;
        else if(a== '>') {
            if (b[--p] != 3) z = 1; // error: bracket type mismatch
        } else if(a== '}') {
            if (b[--p] != 2) z = 1;
        } else if(a== ']') {
            if (b[--p] != 1) z = 1;
        }else if(a== ')') {
            if (b[--p] != 0)z = 1;
        }else z = 1; // error: invalid character
    }
    // if either z or p is not 0 print a '0', otherwise print a '1'
    // if p is not zero that means not all brackets were closed
    // if z is not zero that indicates an erro
    puts(z|p ? "0":"1");
}
```
```
[Answer]
# [Kotlin](https://kotlinlang.org), ~~100~~ ~~89~~ 86 bytes
-11 bytes: Use `any` instead of `firstOrNull`  
-3 bytes: Use `chunked` instead of `split` (thanks to @leo848)
```
fun f(s:String):Boolean="()<>[]{}".chunked(2).any{it in s&&f(s.replace(it,""))}||s==""
```
[Try it online!](https://tio.run/##bVG7bsMwDNz9FQIRBCTQeOhoyB76Cx0VDWpqt0JcybDlIWD07a4cd6jVchDA4x0fp6sPvXVLNzvxZaxDElyIFMNoXUAA@p0h7XOlkTjKJmOloBQZyko2OuYdGEk2SFFpnVVQaY4kWSUGUpKmh@PK2rXdqyJnUyX92Y6QOu/fzJjvgust9P81CYxFsdq04dYNc6jEa0jZB4l6g3uHcIbDo3gGcWrEgbuNSxHoYXOHU/Ujq16871vjalhdWO@F8vI5u2v7js9UGndjG4R1Yjoek6wc26E3lxZteEo/Q/F@n@oaYFm@AQ "Kotlin – Try It Online")
[Answer]
# Python 2, 80 bytes
```
def m(s,i=0):exec's=s.replace("[({<])}>"[i%4::4],"");i+=1;'*4*len(s);return"">=s
```
]