g | x | w | all
Bytes Lang Time Link
056C151005T212126ZJerry Je
066Bash241112T130458ZThemooni
042Zsh241113T061455Zroblogic
007Uiua241113T022526Znyxbird
005Japt f241112T115021ZShaggy
058brainfuck241112T061933Zl4m2
020x86 opcode241112T064932Zl4m2
nan241112T045323Zgurditsb
126Rockstar230608T202524ZShaggy
001Thunno 2 J230608T190222ZThe Thon
013Z80Golf221107T113320ZEasyasPi
034nanoMIPS machine code221107T065049ZEasyasPi
085RProgN160928T013801ZATaco
088C 88 Bytes220328T013252Zuser1117
002Vyxal220325T080825Zemanresu
030Lexurgy220324T155925Zbigyihsu
070Lua220323T231213Ztwentysi
002ngn/k220324T001216Zulucs
034GNU AWK210116T055008ZPedro Ma
021i386 machine code210117T231737ZEasyasPi
008Pyth210118T031342ZScott
023Red210115T114037ZGalen Iv
005Stax210115T104347ZRazetime
019Perl 5 + p151004T163242ZDom Hast
014K ngn/k210114T191249Zcoltim
003Jelly210114T181425Zcaird co
114Scala151005T101739ZLeonardo
021sed E200611T161543ZMitchell
00405AB1E200611T133211ZKevin Cr
9868Ceylon151005T204531ZPaŭlo Eb
9869Ceylon151005T194821ZPaŭlo Eb
026Python 3200609T190733Zxnor
047PHP170517T154447ZJör
059Python170323T125359Zhyperneu
062Python151006T155857Ztobilock
018Beam151004T193749ZMickyT
nanRuby170322T202018ZValue In
079REXX170322T103355Zidrougge
052R160928T012955ZAndre
023Vim160927T230857ZDJMcMayh
047Javascript ES6160628T155811Zuser5418
003APL151006T143820ZMoris Zu
025Octave151029T154229Zalephalp
142AppleScript151029T152756ZAddison
018Gema151029T143650Zmanatwor
010Simplex v.0.7151028T022146ZConor O&
013Minkolang 0.10151028T022814ZEl'e
047C151028T013844Zxsot
032Perl 6151027T234052ZBrad Gil
nan151005T143542Zhvd
066Scala151007T170222ZJoseM
029Haskell151007T002144ZCR Drost
105Python 3151005T013602ZJ F
021Perl 5.10+151006T204317ZThisSuit
062Python 2151006T141541ZZach Gat
061SED151006T132957ZHasturku
318Rust151006T095218ZLiam
5654PHP151006T081326ZNiet the
025JavaScript ES7151005T103138Zazz
096C151005T214416Zmusarith
030Powershell151005T175110Ztomkandy
054MUMPS151005T174948Zsenshin
042Python 2151005T154514Zmbomb007
002GolfScript151005T152403ZIlmari K
078Java151005T133641ZGeobits
033Haskell151005T082306Zxnor
044Python 3151005T080035Zxnor
046JavaScript ES6151005T074201Zedc65
124Befunge93151005T060633ZEl'e
042Julia151004T151437ZGlen O
079Python 2151005T042949ZStatus
018Element151004T145718ZPhiNotPi
016><>151005T011815ZSp3000
111Delphi151005T021429ZJames
079Java151005T012435ZDaniel M
007Pyth151004T233307Zisaacg
046Matlab151004T150102ZLuis Men
7284PHP151004T181705ZFabian S
027Perl151004T162140Zsteve
049TIBASIC151004T183114Zlirtosia
050Haskell151004T182036Zproud ha
014Retina151004T171133ZNinjaBea
023MATLAB151004T152812ZTom Carp
009CJam151004T154228Zaditsu q
024Ruby151004T152507Zmanatwor
047JavaScript ES6151004T150701ZNinjaBea
233Macaroni 0.0.2151004T152903ZDoorknob
nan151004T150952ZProgramF
107AutoIt151004T150817Zuser4264
003CJam151004T145742ZSp3000

C - 56

Thanks to @ceilingcat, @hvd and @AShelly for saving a bunch of characters. There were multiple ways suggested of making it much shorter than the original:

// @ceilingcat      - put vars in for loop
j(char*s){for(char*q=s,*p=s;*q=*p;q+=q==index(s,*p++));}

// @ceilingcat      - use index() instead of strchr()
j(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==index(s,*p++));}

// @hvd             - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

// @AShelly         - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd             - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// original version - requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}

As you can see modifying in place seems to be the shortest (so far!) The test program compiles without warnings using gcc test.c

#include <stdlib.h> // calloc
#include <string.h> // strchr
#include <stdio.h>  // puts, putchar

// 000000111111111122222222223333333333444444444455555555556666666666
// 456789012345678901234567890123456789012345678901234567890123456789

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

/* original version - commented out because it requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}
*/

// The test program:
int main(int argc,char*argv[]){
  char *r=calloc(strlen(argv[1]),1); // make a variable to store the result
  g(argv[1],r);                      // call the function
  puts(r);                           // print the result

  h(argv[1]);                        // call the function which prints result
  puts("");                          // print a newline

  i(argv[1]);                        // call the function (modifies in place)
  puts(argv[1]);                     // print the result
}

Thanks for all the help. I appreciate all the advice given to shorten so much!

Bash, 66 bytes

-9 bytes by roblogic

fold -1|cat -n|sort -k2 -k1n|uniq -f1|sort -nk1,1|cut -f2-|rs -eg0

Try it online!

Explanation:

fold -1|cat -n|sort -k2 -k1n|uniq -f1|sort -nk1,1|cut -f2-|rs -eg0

fold -1                                                               # ‎⁢split string on the empty string
        cat -n                                                        # ‎⁣add line numbers to the beggining of each line (each char)
               sort -k2 -k1n                                          # ‎⁤sort by the second field (the char)
                             uniq -f1                                 # ‎⁢⁡keep only 1 copy of consecutive identitcal lines, ignoring line numbers in the first field
                                      sort -nk1,1                     # ‎⁢⁢sort by line numbers to get back the original order
                                                  cut -f2-            # ‎⁢⁣keep only chars, removing the line numbers
                                                           rs -eg0    # ‎⁢⁤remove trailing newlines of each line, joining each char on the empty string
💎

Created with the help of Luminespire.

Zsh, 42 bytes

for i (${(s::)1})printf "${i:|P}"&&P+=($i)

Try it online!

For each character i in the string $1, if it's not in array P, print it then add it to the array.


A much shorter solution, that breaks the builtin rule, is only 21 bytes: Try it online!

<<<${(j::)${(us::)1}}

Uiua, 7 bytes

⍜⊛⍜°⊚≡±

Try it!

⍜ under ⊛ classifying each character, and ⍜ under °⊚ counting each number, get the ± sign of each count (counts ≥1 become 1).

(The builtin for this is ◴ deduplicate.)

Japt -f, 5 bytes

V¶WbU

Try it

brainfuck, 66 61 58 bytes

,[[->+>+<<]>>[[->>+<<]+>>-]<-[++<[-<<]>.[-]]+<[-<<]>[-]<,]

Try it online!

x86 opcode, 20 bytes

        .intel_syntax noprefix
        .globl .type_uniqchars
        // src: ESI: input string
        // dst: EDI: output buffer (must be big enough)
        // len: ECX: length of string
.type_uniqchars:
        xor eax, eax
        push eax
        push eax
        push eax
.Lloop: lodsb
        bts [esp-4], eax
        jc     .Lloop.duplicate
.Lloop.unique:
        stosb   byte ptr [edi], al
.Lloop.duplicate:
        loop    .Lloop
.Lloop.end:
        add     esp, 12
        ret

Try it online!

Save 3 bytes than EasyasPi by reducing and expanding initialization with 2 byte extra cost checking.

Notice that [esp-4] isn't used as input is ASCII and 32≤eax<127

?

Rockstar, 126 bytes

Listen to I
Cut I
O's ""
While I
Roll I in C
X's 0
P's 1
While O at X
If C's O at X
P's 0

Build X up

If P
Let O be+C


Say O

Try it (Code will need to be pasted in)

Or, if we can output each character individually, on a separate line ...

124 bytes

Listen to I
Cut I
O's ""
While I
Roll I in C
X's 0
P's 1
While O at X
If C's O at X
P's 0

Build X up

If P
Let O be+C
Say C

Thunno 2 J, 1 byte

ċ

Attempt This Online!

Takes the set union with itself (set operations were allowed by OP).

Thunno 2 J, 11 bytes

{DȤsƇ¬?ȥ;}Ȥ

Attempt This Online!

A different answer that doesn't use sets.

Explanation

{DȤsƇ¬?ȥ;}Ȥ  # Implicit input
{        }   # For each character in the input:
 D           #  Duplicate it
  Ȥs         #  Push the global array and swap
    Ƈ¬?      #  If it's not in the global array:
       ȥ;    #   Add it to the global array
          Ȥ  # After the loop, push the global array
             # Implicit output, joined

Z80Golf, 13 bytes

00000000: cd 03 80 38 04 26 ff 6f cb 76 74 c5 c0           ...8.&.o.vt..

Try it online!

Commented assembly:

start:
.loop:
    call  0x8003         ; CD 0380  Read from stdin to A, C is success
    jr    c, .end + 1    ; 38 04    Jump to the 76 in the middle of the bit opcode to halt
    ld    h, 0xFF        ; 26 FF    HL = 0xFFxx
    ld    l, a           ; 6F       HL = 0xFF00+A, address + offset of LUT
.end:
    bit   6, (hl)        ; CB 76    Test bit 6 of the table
    ; halt               ;   (76)      Exit the program with halt (overlaps)
    ld    (hl), h        ; 74       Mark the LUT to 0xFF
    push  bc             ; C5       Push address of .loop for ret (BC is 0x0000)
    ret   nz             ; C0       If bit 6 was set (not unique), ret to .loop
                         ;          otherwise fall through to putchar

This uses the LUT method in my other answers. However it is much easier on Z80Golf because I know the full state of the machine and can optimize for it.

Specifically, I know that the 128 bytes at 0xFF00-0xFF7F will be 0, so I can use that by setting the high byte of HL and the low byte of A.

There are some weird optimizations to make this smaller. I could get 0xFF in h in one byte by dec h, but that introduces a state I have to check. Instead, I suck up the byte for ld h, 0xFF in favor of the entire program being stateless outside of the table. Then, I can use push bc followed by ret nz to loop if nonzero or fall through the nop sled to putchar otherwise.

nanoMIPS machine code, 34 bytes

00000000: 80 1c a0 d3 fc 90 a7 23 87 04 80 bb c0 5f 89 90  .......#....._..
00000010: a7 23 07 30 00 bb a7 23 87 38 d4 5f a9 90 80 bb  .#.0...#.8._....
00000020: 80 1d                                            ..

Commented assembly:

    .globl uniqchars
    # Type uniqchars! for nanoMIPS, Yet Another Weird MIPS Extension
    # Follows C calling convention
    #    void uniqchars(const char *input, char *output);
    # Input:
    #    a0: pointer to a null terminated ASCII string
    #    a1: pointer to an adequately sized buffer
    # Output:
    #    Null terminated ASCII string stored to a1
uniqchars:
    # Create a 128 byte stack buffer for a lookup table
    # Equivalent normieMIPS:
    #  addiu $sp, -128
    save     128
    # Clear the buffer
    li       $a3, 128 / 4
.Lclear:
    # Decrement index
    addiu    $a3, -4
    # Behold! MIPS finally added register-register addressing!
    # And only like 31 years late!
    #  addiu $at, $sp, $a3
    #  sw    $zero, ($at)
    swx      $zero, $a3($sp)
    # Loop if not zero
    bnez     $a3, .Lclear
    # Loop through the string
.Lloop:
    # Load byte from a0
    lb       $a3, ($a0)
    # Increment pointer
    addiu    $a0, 1
    # Load byte from lookup table
    lbx      $a2, $a3($sp)
    # If it is nonzero, this char is not unique. Try the next one.
    bnez     $a2, .Lloop
    # Store the char itself to the lookup table
    sbx      $a3, $a3($sp)
    # Store the char to the output string
    sb       $a3, ($a1)
    addiu    $a1, 1
    # Loop if it was not a null terminator
    bnez     $a3, .Lloop
    # Clean up the stack and return
    #  addiu $sp, 128
    #  jr    $ra
    restore.jrc 128

This uses the new nanoMIPS calling convention, and can be called from C with the following prototype:

void uniqchars(const char *input, char *output);

Yes. This is the third compressed variant of the MIPS instruction set. All three of which are incompatible.

At least it golfs decently. thumb > all

Aside from a few "hybrid instructions" added, it is just normal MIPS in shorthand.

A GCC toolchain, QEMU port, and documentation links are in the link above. Note that for some reason the Windows port lacks qemu-nanomips and both Linux and Windows versions crash on my system unless I run it in qemu-x86_64 itself. 🤔

RProgN, 85 Bytes

S i 'a' = s 'n' = a L while a pop 'b' = n b hasvalue ! if n b push end a L end n i ++

Explanation

S i                     # Take the implicit string input, convert it to a stack such that the first letter is at the bottom, invert the stack such that the first letter is at the top.
'a' =                   # Associate it with 'a'
s 'n' =                 # Create a new stack, associate it with 'n'
a L                     # Push the size of a
while                   # While the top of the stack contains a truthy value
    a pop 'b' =         # Pop the top of a, associate it with 'b'
    n b hasvalue !      # Push if the stack 'n' does not contain b
    if                  # If the top of the stack is truthy
        n b push        # Push b to the stack n
    end                 #
    a L                 # Push the length of a
end                     # loop
n i ++                  # Push the n, inverts it, sums it, which acts to concatenate it, implicitly print the result.

C - 88 Bytes

r[99];b;a;main(i){for(;read(i=0,&b,1);99-i?b=0:putchar(r[a++]=b))for(;i<99&&b-r[i++];);}

Thanks to @ceilingcat because I saved 20 bytes with his modification.

Ungolfed

r[99]; b; a;

main(i) {
    for(; read(0, &b, 1); 99 - i?b = 0: putchar(r[a++] = b))
       for(i = 0; i < 99 && b - r[i++]; ); }

Explanation

Characters are read from the console, which are searched for within a list containing all the repeated characters found so far, as the characters are read, the list is updated, with new characters being added at the end of the list. If a character is repeated it is not printed.

This code was tested on GCC and it generates some warnings but it compiles and works fine (although it is not the most optimized code).

Vyxal, 2 bytes

ƒ∪

Try it Online!

Reduce by set union. Port of caird's answer.

Vyxal, 3 bytes

ÞU*

Try it Online!

Multiply by uniquify mask.

Lexurgy, 30 bytes

Due to how Lexurgy handles whitespace, it expects whitespace to be replaced with some other character, such as _.

a propagate:
[]$1=>*/$1 []* _

Explanation

a propagate:        # rule a: while the current string changed last run...
[]$1                # match anything...
    =>              # and replace with...
      *             # empty string
       /            # when the input...
        $1          # starts with the captured char
          []*       # followed by any number of anything
             _      # then a captured char

Lua, 70 bytes

l={}print(((...):gsub('.',function(c)c=l[c]or c;l[c]=''return c end)))

Attempt This Online! Stores the characters in the table after gsub walks through the whole string. Strings are truthy values in Lua so when list[character] is nil, the character is returned the first time then it is replaced with an empty string after the assignment.

ngn/k (2 bytes)

!=

= produces a dict that shows where each element is located, ! takes the keys.

GNU AWK, 35 34 bytes

BEGIN{RS=".|";ORS=e}!a[RT]++,$0=RT

Try it online!

This is a major edit of my first version. In fact, it changed entirely. Only works in GNU AWK, due to the RT variable.

BEGIN{RS=".|";ORS=e}

RS=".|" works like the /./ regex, so every character of the input is considered a record separator. The practical use is that RT returns each character at a time. ORS=e prevents newlines from appearing.

!a[RT]++,$0=RT

A simple AND gate. This is a range pattern. The left part: current RT element of the a array is incremented by 1, but it is evaluated by the NOT gate before the increment. Returns TRUE only the first time a character appears. The right part: assigns the current character (RT) to the input/output $0; only happens when beginning pattern is true, i.e., the first time a character appears.

AWK, 48 bytes (former answer)

split($0,a,e){for(i in a)printf a[j=a[i]]++?e:j}

Try it online!

{
split($0,a,e); # Splits the input into the _a_ array, one char for each element.
               # _e_ variable is not assigned, and returns "".

for(i in a)            # For each element _i_ of the array _a_,
  printf
         a[j=a[i]]++?  # if the element a[i] (AKA j) is positive (i.e, true),
                  ^--- (This also increments this element by 1 after evaluating it)
                   e:  # prints _e_ (AKA "")
                   j   # if it's zero (AKA not assigned, AKA false), prints a[i].
}

i386 machine code, 22 21 bytes

Machine code:

00000034  6a 20 59 6a ff e2 fc 91  ac d0 2c 04 71 01 aa e2  |j Yj......,.q...|
00000044  f7 83 ec 80 c3                                    |.....|
00000049

Commented assembly:

        .intel_syntax noprefix
        .globl .type_uniqchars
        // dst: EDI: output buffer (must be big enough)
        // src: ESI: input string
        // len: EAX: length of string
.type_uniqchars:
        // Set ECX to 32
        push    32
        pop     ecx
        // Create a 128 byte buffer on the stack of all 1 bits
        // by pushing -1 32 times.
        // We only need 128 bytes because we know that
        // we are only dealing with ASCII.
.Lpush_loop:
        push    -1
        loop    .Lpush_loop
.Lpush_loop.end:
        // ECX = len
        // EAX = 0 (because of the loop)
        xchg    ecx, eax
.Lloop:
        // AL = *src++;
        lodsb   al, byte ptr [esi]
        // This is taking advantage of this quirk with SHR:
        //
        //   The OF flag is affected only on 1-bit shifts [...]
        //   For the SHR instruction, the OF flag is set to the
        //   most-significant bit of the original operand.
        //
        // So basically, we do this:
        //
        //     unique     duplicate
        //   0b11111111  0b01111111
        //     |\\\\\\\    |\\\\\\\
        //  OF:1||||||| OF:0|||||||
        //   0b01111111  0b00111111
        //
        // I chose this over INC+JNZ because this will never
        // overflow: it will just stay at zero.
        shr     byte ptr [esp + eax]
        // No overflow means duplicate
        jno     .Lloop.duplicate
.Lloop.unique:
        // *dst++ = AL
        stosb   byte ptr [edi], al
.Lloop.duplicate:
        // Loop while there is still data
        loop    .Lloop
.Lloop.end:
        // Clean up the stack and return.
        // Note that sub esp, -128 is smaller than add esp, 128.
        sub     esp, -128
        ret

Try it online!

char *.type_uniqchars(char *dst {edi}, const char *src {esi}, size_t len {eax})

A pointer one byte past the end of the output string will be returned in edi. However, in the test code, I just null terminate because it is easier to print that way.

Doesn't follow standard calling convention, hence the leading dot.

Explanation (see comments for more)

This uses a lookup table on the stack, which is set to -1. It is 128 bytes because we are only dealing with ASCII.

Then, this magic is used:

        shr     byte ptr [esp + eax]
        jno     .Lloop.duplicate

This uses the fact that a one bit shr will put the most significant bit in the overflow flag. The first time, the overflow flag will be set since all bits are set, but then that most significant bit will be shifted out.

Unlike something like this:

        inc     byte ptr [esp + eax]
        jnz     .Lloop.duplicate

You could run this 1, 10, 100000 times, and it will never fail. That inc solution will fail after 256 duplicates as it wraps around to zero. Shifting right will just end up at zero and stay there indefinitely.

Other than that, it is a pretty straightforward string copy routine.

Pyth, 8 bytes

s.gxQk.|

Try it online!

  1. Bitwise Or the input
  2. Group the input by:
  3. It's index in the original input
  4. Join list and print.

Red, 23 bytes

func[s][union/case s s]

Try it online!

Using a map!, 58 bytes

func[s][m: copy #()foreach c s[put m c c]rejoin keys-of m]

Try it online!

A naive implementation, 69 bytes

func[s][rejoin collect[foreach c s[unless find collected c[keep c]]]]

Try it online!

Stax, 5 bytes

╤•╗jP

Run and debug it

Perl 5 + -p, 19 bytes

Saved 1 byte thanks to @kos and 1 byte thanks to @Xcali!

s/./$&x!$h{$&}++/eg

Try it online!

K (ngn/k), 14 bytes

{x@&(!#x)=x?x}

Try it online!

A ngn/k implementation of the classic APL idiom for unique-ifying a list.

Jelly, 3 bytes

œ|/

Try it online!

Simply reduces by set union

Slightly more creative, but relies on "unique sieve" functions not being banned:

xŒQ

Try it online!

How it works

xŒQ - Main link. Takes a string S on the left
 ŒQ - Unique sieve; For each character in S, replace it with 1 if it hasn't occurred yet, else 0
x   - Repeat each character in S according to the corresponding value in the sieve
    - Implicitly print, mashing empty strings into the output

Scala, 118114 bytes

def f(a:String):String=a.zipWithIndex.groupBy(_._1.toLower).map(_._2.head).toList.sortBy(_._2).map(_._1).mkString

sed -E, 21 bytes

:L;s/((.).*)\2/\1/;tL

Try it online!

05AB1E, 5 4 bytes

ʒkNQ

Try it online or verify all test cases.

Slightly more interesting previous 5 bytes version:

SkāαÏ

Try it online or verify all test cases.

Explanation:

ʒ     # Filter the characters in the (implicit) input-string by:
 k    #  Get the first index of the current character in the (implicit) input-string
  NQ  #  Check if it's equal to the filter-index
      # (after which the result is output implicitly)

S     # Convert the (implicit) input-string to a list of characters
 k    # Get the first 0-based index of each character in the (implicit) input-string
  ā   # Push a list in the range [1, list-length] (without popping)
   α  # Get the absolute difference between the values at the same positions in the lists
    Ï # Keep the characters of the (implicit) input-string at the truthy (==1) indices
      # (after which the result is output implicitly)

With builtins allowed, this would of course be a single byte: Ù
Try it online or verify all test cases.

Ceylon, 98 bytes (stdio) / 68 bytes (function)

Here is a version without using Set or similar stuff, as a function (68 bytes):

String i(String s)=>String{for(x->c in s.indexed)if(!c in s[0:x])c};

The same with stdio (reading just one line) (98 bytes):

void q(){value s=process.readLine()else"";print(String{for(x->c in s.indexed)if(!c in s[0:x])c});}

The first one ungolfed (117 bytes):

String i(String s) => String{
        for (x->c in s.indexed)
            if (!c in s[0:x])
                c
    };

This uses the feature to build a string from an iterable of characters, but this time the iterable is build from a comprehension, which is passed to the string-constructor using the named-argument-list syntax. (This could also have been written as String({...});, using a positional argument list and an iterable-constructor, but that would have been two bytes more).

The comprehension consists of a for-clause (which iterates over an indexed version of the input string, i.e. x is the index corresponding to the character c) and an if-clause (which filters the character by checking if it appears in the substring up to the index).

We see here two different uses of the keyword in – once as part of the syntax of the for clause of comprehensions, and once as the in operator, which maps to s[0:x].contains(c).

The "thin arrow" in x->c is the syntax for an Entry made of x and c (as key and value). As an expression one can build an entry this way from its constituents, but here it is a part of the comprehension syntax (and also the syntax of the for-loop), and deconstructs the entry which is returned by the iterator of the iterable s.indexed.

The "fat arrow" => is a shorthand for defining a function whose body consists of just one expression (which is evaluated and returned) – that saves us the return and a pair of braces.

The variant which uses stdio:

void q() {
    value s = process.readLine() else "";
    print(String { for (x->c in s.indexed)
                if (!c in s[0:x])
                    c });
}

Unfortunately we need a variable here to store the string, because we need to access it twice (in the loop and in the filter).


Instead of using an Iterable comprehension, we can also use the stream-manipulating method filter together with the spread attribute operator *. and a lambda expression (e)=>!e.item in s[0:e.key] inbetween:

String j(String s)=>String(s.indexed.filter((e)=>!e.item in s[0:e.key])*.item);

This is even longer with 79 bytes.

Ceylon, 98 bytes (stdio) / 69 bytes (function)

This version is using stdio and a HashSet, 98 bytes:

import ceylon.collection{H=HashSet}shared void u(){print(String(H{*(process.readLine()else"")}));}

This is just a function String → String (also using a HashSet), 69 bytes:

import ceylon.collection{H=HashSet}String n(String i)=>String(H{*i});

Ungolfed version:

import ceylon.collection {
    HashSet
}
void uniq() {
    value input = process.readLine() else "";
    value set = HashSet { elements = input; };
    print(String(set));
}

A Ceylon HashSet by default is linked (i.e. conserves the insertion order as iteration order). We use here the named-argument syntax to pass the elements argument to the HashSet constructor.

A string is also an iterable of characters, and as such can be passed to the elements parameter. A string can also be constructed from such a sequence, which is what we do in the last command.

The golfed version again: import ceylon.collection{H=HashSet}shared void u(){print(String(H{*(process.readLine()else"")}));}

Some used tricks:

If we don't have to handle standard-input and output and just need a function, this is shorter:

import ceylon.collection{HashSet}
String n(String i) => String(HashSet{*i});

The explanations from above are still valid.

Python 3, 26 bytes

lambda s:[*dict(zip(s,s))]

Try it online!

Reviving an ancient question with a new idea, inspired by Noodle9's solution to "Special String reformatting" and my further refinement.

Because Python 3's dictionaries automatically remove duplicate keys beyond the first appearance while keeping them in order, we convert the the input string to a dictionary as keys. We then convert the dictionary back to a list with iterable unpacking, which extracts its keys. (The challenge seems to be fine with a list of characters in lieu of a string, asking for a "sequence of chars".)

While we could make the dictionary via a comprehension like {c:1for c in s}, it's one byte shorter to use the dict constructor as dict(zip(s,s)), which each character is both the key and the values. A same-length alternative is {}.fromkeys(s).

Note that while set does also remove duplicates, it fails to keep them in order, and is also disallowed by the challenge.

PHP, 47 Bytes

for(;a&$c=$argn[$i++];)$r[$c]=$c;echo join($r);

Try it online!

Python, 61 59 bytes

lambda s:''.join(i for c,i in enumerate(s)if s.index(i)==c)

str.index always returns the first occurrence, so only output the character if the current occurrence is the first occurrence.

Edit: The square brackets were unnecessary.

Python, 62 bytes

lambda s:''.join([c for i,c in enumerate(s)if c not in s[:i]])

Beam, 23 18 bytes

v<H
vs)
rS
g@S
>u^

enter image description here

Try it online!

Ruby, 19 + 1 = 20 bytes

Uses the -p flag. Uses set operations like the GolfScript answer, which is totally not a built-in like uniq. (Performing set or on a list and an empty list purges the list of duplicates, just like calling and against a copy of itself.)

$_=($_.chars|[])*""

REXX, 79 bytes

a=arg(1)
o=
do while a>''
  parse var a b+1 a
  if pos(b,o)=0 then o=o||b
  end
say o

R, 52 bytes

cat(union(a<-strsplit(readline(),"")[[1]],a),sep="")

Test examples:

Type uniqchars!
"I think'sdarloe,yu
3.14592687

Vim, 23 keystrokes

qq:s/\v(.).*\zs\1<cr>@qq@q

Explanation:

qq                           " Start recording into register 'q'
  :s/                        " Search and replace:
      \v                     " Enable 'magic', which just makes regexes a littl shorter
        (.)                  " Any symbol, captured in group one
           .*                " Anything
             \zs\1           " Start selection, group one
                             " Replace with nothing
                  <cr>       " Globally
                      @q     " Call macro q. Since we are still recording, this will not do anything the first time, and create a loop the next time
                        q    " Stop recording. 
                         @q  " Start the loop. This will run until there is no match.

Since V is backwards compatible, you can Try it online!

Javascript (ES6), 47 bytes

a=>[...a].filter((b,c)=>a.indexOf(b)==c).join``

Test it here

Some code is added to have a better input and to write to the console the result.

d=document,g=d.getElementById.bind(d);g("s").onclick=e=>console.log((a=>[...a].filter((b,c)=>a.indexOf(b)==c).join``)(g("t").value))
<input id="t"><button id="s">Convert</button>

APL, 3

∊∪/

This applies union (∪) between each element of the vector, obtaining an iteration that has the effect of removing duplicates.

Test it on tryapl.org

Old One:

~⍨\

This uses ~ (with reversed arguments, using ⍨) applied between each element of the argument. The result is that for each element, if it's already in the list, it gets erased.

Octave, 25 bytes

@(s)s(sum(triu(s'==s))<2)

AppleScript, 143 142 Bytes

set x to(display dialog""default answer"")'s text returned's characters
set o to""
repeat with i in x
if not i is in o then set o to o&i
end
o

Not a language for golfing, but it's very readable.

Gema, 18 characters

?=${?;$0}@set{$0;}

Sample run:

bash-4.3$ gema '?=${?;$0}@set{$0;}' <<< 'hello world'
helo wrd

Simplex v.0.7, 22 10 bytes

s^oR^l^Ryg
s          ~~ string input
 ^o        ~~ convert to tuple
   R       ~~ go right
    ^l     ~~ unicode tuple
      ^R   ~~ take intersection
        yg ~~ convert to string and output

sigh Minkolang is kicking Simplex's butt.

s^[oZ%_Q]n?[^_s^~M^=]]
s                      ~~ string input
 ^[     ]              ~~ postfixes each of the inner with a ^
   o                   ~~ convert to tuple
    Z                ] ~~ fold
     %                 ~~ tuple w/out current character + increment
      _                ~~ current character
       Q               ~~ membership
         n?[        ]  ~~ if current character not in tuple
            ^_s^~M^=   ~~ print that character 

Minkolang 0.10, 13 bytes

This language was made after this challenge but not for this challenge.

Much thanks to Sp3000 for pointing me the way to this much shorter solution.

od?.dd0q?Od0p

Try it here.

Explanation

od               Read character from input and duplicate it (for the conditional)
  ?.             Stop if 0 (i.e., input is empty)
    dd           Duplicate twice (for q and for possible output)
      0q         Gets value stored in (character,0) in the codebox (0 if empty)
        ?O       Outputs character if it's unique (i.e. the previous value was 0)
          d0p    Puts the value of the character at (value,0) in the codebox

C, 47 bytes

a[];main(c){for(;read(0,&c,1);write(!a[c]++));} 

Perl 6, 32 bytes

The way you would normally write this would be:

$*IN.comb.unique.print # it would have been 22

Which would have had the benefit of being obviously correct.


Instead I have to write something like the following

print $*IN.comb.grep:{!.{$^a}++} # 32

C# 6 - 18+46=64

using System.Linq;

and then

string f(string s)=>string.Concat(s.Union(s));

The Enumerable.Union extension method specifies that elements are returned in the original order:

When the object returned by this method is enumerated, Union enumerates first and second in that order and yields each element that has not already been yielded.

Set operations that aren't specifically intended to find unique values appear to be allowed judging by the other answers.

Scala, 79, 66 bytes

Inspired by the Haskell version using foldLeft

def f(s:String)=s.foldLeft("")((a,c)=>if(a.contains(c))a else a+c)

Previous version using zipWithIndex and collect

def f(s:String)=s.zipWithIndex.collect{case(c,i)if s.indexOf(c)==i=>c}.mkString

Haskell, 29 bytes

Nestable, no-variable-name one-liner:

foldr(\x->(x:).filter(x/=))[]

Same count, saved into a function named f as a top-level declaration:

f(x:t)=x:f[y|y<-t,x/=y];f_=[]

Note that there is a slightly-cheating optimization which I haven't made in the spirit of niceness: it is technically still allowed by the rules of this challenge to use a different input and output encoding for a string. By representing any string by its partially-applied Church encoding \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b] (with the other side of the bijection provided by the function ($ (:))) this gets golfed down to ($ \x->(x:).filter(x/=)), only 24 characters.

I avoided posting the 24-character response as my official one because the above solution could be tried on the above interpreter as foldr(\x->(x:).filter(x/=))[]"Type unique chars!"whereas the golfed solution would be written instead:

($ \x->(x:).filter(x/=))$ foldr (\x fn f->f x (fn f)) (const []) "Type unique chars!"

as a shorthand for the literal declaration which would be the more-insane:

($ \x->(x:).filter(x/=))$ \f->f 'T'.($f)$ \f->f 'y'.($f)$ \f->f 'p'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'u'.($f)$ \f->f 'n'.($f)$ \f->f 'i'.($f)$ \f->f 'q'.($f)$ \f->f 'u'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'c'.($f)$ \f->f 'h'.($f)$ \f->f 'a'.($f)$ \f->f 'r'.($f)$ \f->f 's'.($f)$ \f->f '!'.($f)$ const[]

But it's a perfectly valid version of the data structure represented as pure functions. (Of course, you can use \f -> foldr f [] "Type unique chars!" too, but that is presumably illegitimate since it uses lists to actually store the data, so its foldr part should then presumably be composed into the "answer" function, leading to more than 24 characters.)

Python 3, 132 109 105 bytes

u=[]
def t(l):
 if l in u:return''
 else:
  u.append(l);return l
print(''.join([t(l)for l in input()]))

Ungolfed:

used_chars = []
def test(letter):
    if letter in used_chars:
        return '' # skip
    else:
        used_chars.append(letter)
        return letter
print(''.join([test(letter) for letter in input()]))

Perl 5.10+, 21 bytes

perl -pe '1while s/(.).*\K\1//'

20 bytes + 1 byte for -p. Note that Perl 5.10 or above is required for \K.

Takes input from stdin:

$ echo 'Type unique chars!' | perl -pe '1while s/(.).*\K\1//'
Type uniqchars!

$ echo \"I think it\'s dark and it looks like rain\", you said | perl -pe '1while s/(.).*\K\1//'
"I think'sdarloe,yu

$ echo 3.1415926535897932384626433832795 | perl -pe '1while s/(.).*\K\1//'
3.14592687

Online demo


Inspired by NinjaBearMonkey's Retina answer. Perl may not have a compact way to re-run a substitution until nothing changes, but it does have \K, which causes the regex engine to "keep" everything to its left. This allows you to drop a set of parentheses on the LHS and a capture variable on the RHS:

s/(.).*\K\1//   # 13 bytes

vs.

s/((.).*)\2/$1/ # 15 bytes

Python 2, 62 bytes

s=set();print filter(lambda i:not(i in s or s.add(i)),input())

SED, 61 bytes

s/^/\a/
:
s/\a\(\(.\).*\)\2/\a\1/
t
s/\a\(.\)/\1\a/
t
s/\a//

Rust, 318 Bytes

not really a competitor, but rust needs a bit more love. As always, comments and advice welcome.

use std::io;fn main(){let mut s=io::stdin();let mut b=String::new();s.read_line(&mut b).unwrap();let mut n: Vec<char>=b.chars().collect();for i in 0..n.len()-2{let mut j=i+1;let mut p = true;while j<n.len(){if j<n.len(){if n[i]==n[j]{n.remove(j);p=false;}}if p{j+=1;}p=true;}}for i in 0..n.len()-2{print!("{}",n[i]);}}

Try it online here (first compile, then execute, then click into the proper area to enter user input)

ungolfed:

use std::io;
fn main() {
let mut s = io::stdin();
let mut b=String::new();
s.read_line(&mut b).unwrap();
let mut chars: Vec<char> = b.chars().collect();
for i in 0..chars.len()-2 {
    let mut j=i+1;
    let mut inc = true;
    while j<chars.len() {
        if j<chars.len() 
        {
            if chars[i]==chars[j] {
                chars.remove(j);
                inc = false;
            }
        }
        if inc {
            j+=1;
        }
        inc = true;
    }
}
for i in 0..chars.len()-2 {
    print!("{}",chars[i]);
}
}

PHP, 56 54

// 56 bytes
<?=join('',array_flip(array_flip(str_split($argv[1]))));

// 54 bytes
<?=join(!$a='array_flip',$a($a(str_split($argv[1]))));

Edging out @fschmengler's answer using array_flip twice - second version uses variable method and relies on casting the string to true, negating it to false, then casting it back to the empty string in the first argument to save a couple of bytes in the second. Cheap!

JavaScript ES7, 37 33 25 bytes

Pretty simple approach using ES6 Set and ES7 Array comprehensions spread operator:

s=>[...new Set(s)].join``

22 bytes less than the indexOf approach. Worked on a handful of test cases.

C, 96 bytes

#include<stdio.h> 
int c,a[128];main(){while((c=getchar())-'\n')if(!a[c])a[c]=1,putchar(c);}

This uses an array of integers, indexed by ASCII character number. The characters are only printed if that place in the array is set to FALSE. After each new character is found that place in the array is set to TRUE. This takes a line of text from standard input, terminated by a newline. It ignores non-ASCII characters.


Ungolfed:

#include<stdio.h>
#include<stdbool.h>

int main(void)
{
  int i, c;
  int ascii[128];
  for (i = 0; i < 128; ++i) {
    ascii[i] = false;
  }
  while ((c = getchar()) != '\n') {
    if (ascii[c] == false) {
      ascii[c] = true;
      putchar(c);
    }
  }
  puts("\n");
  return(0);
}

Powershell, 30

$args-replace'(.)(?<=\1.+)',''

I feel there's likely to be a better regex than this, and I can't work out what it is

MUMPS, 54 bytes

f(s) f i=1:1:$L(s) s c=$E(s,i) s:t'[c o=o_c,t=t_c
    q o

Not terribly exciting - it just keeps a running list of already-viewed characters and only appends to the output string if the current character isn't in that list.

Python 2, 42 bytes

Uses a couple anonymous functions and reduce.

lambda s:reduce(lambda x,y:x+y[y in x:],s)

Try it online

GolfScript, 2 bytes

.&

or, alternatively:

.|

I posted this a while ago in the Tips for golfing in GolfScript thread. It works by duplicating the input string (which is put on the stack automatically by the GolfScript interpreter, and which behaves in most ways like an array of characters) and then taking the set intersection (&) or union (|) of it with itself. Applying a set operator to an array (or string) collapses any duplicates, but preserves the order of the elements.

Java, 78 bytes

String f(char[]s){String t="";for(char c:s)t+=t.contains(c+"")?"":c;return t;}

A simple loop while checking the output for characters already present. Accepts input as a char[].

Haskell, 33 bytes

foldl(\r c->r++[c|notElem c r])[]

Uses foldl to iterate through the string appending characters that are not in the current result, starting with the empty string (list).

Python 3, 44

r=''
for c in input():r+=c[c in r:]
print(r)

Builds the output string r character by character, including the character c from the input only if we haven't seen it already.

Python 2 would be 47, losing 4 chars with raw_input and saving 1 on not needing parers for print.

JavaScript (ES6) 46

f=s=>[...s].map(c=>s[c]?'':s[c]=c,s=[]).join``

Unexpectedly, this time the flag array is one byte shorter than the indexOf approach.

Befunge-93, 124 bytes

v
<v1p02-1
0_v#`g00: <0_@#+1::~p
 1>:1+10p2+0g-!#v_v
g `#v_10g0^       >:10g00
 ^0g 00$        <
 ^  >:,00g1+:00p1+:1+01-\0p

Test it in this online interpreter.


This was more difficult than I expected. I'll post a fuller explanation tomorrow if anyone wants me to, but here's an overview of what my code does.

Julia, 45 42 bytes

s->(N="";[i∈N?N:N=join([N,i])for i=s];N)

Old version:

s->(N={};for i=s i∈N||(N=[N,i])end;join(N))

Code builds the new string by appending new characters onto it, then joins them together to a proper string at the end. New version saves some characters by iterating via array comprehension. Also saves a byte by using ?: rather than || (as it removes the need for brackets around the assignment).

Alternate solution, 45 bytes, using recursion and regex:

f=s->s!=(s=replace(s,r"(.).*\K\1",""))?f(s):s

Julia, 17 bytes

(Alternate version)

s->join(union(s))

This uses union as basically a substitute for unique - I don't consider this the "real" answer, as I interpret "don't use unique" to mean "don't use a single built-in function that has the effect of returning the unique elements".

Python 2, 79

def S(s):
 s=s[::-1]
 for c in s:s=s.replace(c,'',s.count(c)-1)
 return s[::-1]

It reverses the input string, cycles through it, replaces any extra characters with null ones and returns the reverse of that. The reverse is so the last characters are removed, not the first.

>>> S('''"I think it's dark and it looks like rain", you said''')
'"I think\'sdarloe,yu'
>>> S("3.1415926535897932384626433832795")
'3.14592687'
>>> S("Type unique chars!")
'Type uniqchars!'

Element, 22 19 18 bytes

_'{"(3:~'![2:`];'}

Example input/output: hello world -> helo wrd

This works by simply processing the string one character at a time and keeping track which ones it has seen before.

_'{"(3:~'![2:`];'}
_                        input line
 '                       use as conditional
  {              }       WHILE loop
   "                     retrieve string back from control (c-) stack
    (                    split to get the first character of (remaining) string
     3:                  a total of three copies of that character
       ~                 retrieve character's hash value
        '                put on c-stack
         !               negate, gives true if undef/empty string
          [   ]          FOR loop
           2:`           duplicate and output
               ;         store character into itself
                '        put remaining string on c-stack as looping condition

><>, 16 bytes

i:0(?;:::1g?!o1p

><> doesn't have strings, so we make use of the codebox. Due to the toroidal nature of ><>, the following runs in a loop:

i         Read a char
:0(?;     Halt if EOF
:::       Push three copies of the char
1g        Get the value at (char, 1), which is 0 by default
?!o       Print the char if the value was nonzero
1p        Set the value at (char, 1) to char

Note that this uses the fact that the input only contains printable ASCII, as this would not work if ASCII 0 was present.

Delphi, 111 bytes

procedure u(var s:string);var i:word;begin for i:=length(s) downto 1 do if pos(s[i],s)<i then delete(s,i,1)end;

Using the procedure to alter the passed in string - saves a few bytes in comparison to declaring the function. Moving backwards through the string, delete the current character if it is not the first location of that character

Java, 79 bytes

It's java, and it may be a little bit shorter than some of the more wordy esoteric languages.

But still, java.

s->{String r="";for(char c:s.toCharArray())r+=(r.indexOf(c)>-1)?"":c;return r;}

Explanation:

s->{ //Lambda expression opening, note that java can infer the type of s

    String r=""; //Initializes String r

    for(char c:s.toCharArray()) //Iterates through the string

        r+=(r.indexOf(c)>-1)?"":c; //indexOf(c) returns -1 if there are no occurrences

    return r;

}

Pyth, 7 bytes

soxzN{z

Pseudocode:

z = input

sum of order-by index in z of N over set of z.

Matlab, 46 bytes

It uses an anonymous function, with function arguments as input and output:

@(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

(I couldn't get this to work in an Octave online interpreter.)

Example use:

>> @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')
ans = 
    @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

>> ans('Type unique chars!')
ans =
Type uniqchars!

PHP, 72 Bytes 84 Bytes

<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));

Uses the characters as keys for an associative array, then prints the keys. Order of array elements is always the order of insertion.

Thanks Ismael Miguel for the str_split suggestion.

Perl, 54 27 bytes

map{$h{$_}||=print}<>=~/./g
123456789012345678901234567

Test:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$

TI-BASIC, 49 bytes

Input Str1
"sub(Str1,X,1→Y₁
Y₁(1
For(X,2,length(Str1
If not(inString(Ans,Y₁
Ans+Y₁
End
Ans

The equation variables are rarely useful since they take 5 bytes to store to, but Y₁ comes in handy here as the Xth character of the string, saving 3 bytes. Since we can't add to empty strings in TI-BASIC, we start the string off with the first character of Str1, then loop through the rest of the string, adding all characters not already encountered.

prgmQ
?Why no empty st
rings? Because T
I...
Why noemptysrig?Bcau.

Haskell, 50

f=concat.(tail>>=zipWith(\x y->[last x]\\y)).inits

Retina, 14 bytes

+`((.).*)\2
$1

Each line should go in its own separate file, or you can use the -s flag to read from one file.

To explain it, we'll use this longer but simpler version:

+`(.)(.*)\1
$1$2

The first line is the regex to match with (+` is the configuration string that keeps running until all replacements have been made). The regex looks for a character (we'll call it C), followed by zero or more arbitrary characters, followed by C. The parentheses denote capturing groups, so we replace the match with C ($1) and the characters in between ($2), removing the duplicate of C.

For example, if the input string was unique, the first run would match uniqu, with u and niq as $1 and $2, respectively. It would then replace the matched substring in the original input with uniq, giving uniqe.

MATLAB, 23

 @(n)union(n,n,'stable')

Does the "set union" of the input string with itself, using the 'stable' method which does not sort, and then prints.

This works because union returns only non-duplicate values after the merge. So essentially if you union the string with itself, it first produces a string like Type unique chars!Type unique chars!, and then removes all duplicates without sorting.

No need for unique :)

CJam, 9

Lq{1$-+}/

This doesn't convert a string to a set, but it performs a kind of set difference to determine whether a character is found in a string. Try it online

Explanation:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  1$    copy the previous string
  -     subtract from the character (set difference),
         resulting in the character or empty string
  +     append the result to the string

Another version, 13 bytes:

Lq{_2$#)!*+}/

This doesn't do anything related to sets. Try it online

Explanation:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  _     duplicate the character
  2$    copy the previous string
  #)    find the index of the character in the string and increment it
  !     negate, resulting in 0 if the character was in the string and 1 if not
  *     repeat the character that many times
  +     append the result to the string

Ruby, 30 24 characters

(23 characters code + 1 character command line option.)

gsub(/./){$`[$&]?"":$&}

Sample run:

bash-4.3$ ruby -pe 'gsub(/./){$`[$&]?"":$&}' <<< 'hello world'
helo wrd

JavaScript ES6, 47 bytes

f=s=>s.replace(/./g,(e,i)=>s.indexOf(e)<i?'':e)

The test below works on all browsers.

f=function(s){
  return s.replace(/./g,function(e,i){
    return s.indexOf(e)<i?'':e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="Type unique chars!" /><button id="run">Run</button><br />
<pre id="output"></pre>

Macaroni 0.0.2, 233 bytes

set i read set f "" print map index i k v return label k set x _ set _ slice " " length index f e 1 1 set f concat f wrap x return label e set _ slice " " add _ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return

This is a full program, which inputs from STDIN and outputs on STDOUT.

Wrapped version, for aesthetic value:

set i read set f "" print map index i k v return label k set x _ set _ slice "
" length index f e 1 1 set f concat f wrap x return label e set _ slice " " add
_ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return

And a heavily "commented" and ungolfed version (there are no comments in Macaroni, so I just use bare string literals):

set input read                  "read line from STDIN, store in 'input' var"
set found ""                    "we need this for 'keep' below"
print map index input keep val  "find indeces to 'keep', map to values, print"
return

label keep
    "we're trying to determine which indeces in the string to keep. the special
     '_' variable is the current element in question, and it's also the value
     to be 'returned' (if the '_' variable is '0' or empty array after this
     label returns, the index of the element is *not* included in the output
     array; otherwise, it is"
    set x _ set _ slice
        " "
        length index found exists
        1
        1
    "now we're using 'index' again to determine whether our '_' value exists in
     the 'found' array, which is the list of letters already found. then we
     have to apply a boolean NOT, because we only want to keep values that do
     NOT exist in the 'found' array. we can 'invert' a boolean stored as an
     integer number 'b' (hence, 'length') with 'slice(' ', b, 1, 1)'--this is
     equivalent to ' '[0:1], i.e. a single-character string which is truthy, if
     'b' was falsy; otherwise, it results in an empty string if 'b' was truthy,
     which is falsy"
    set found concat found wrap x  "add the letter to the 'found' array"
return

label exists
    set _ slice
        " "
        add _ multiply -1 x
        1
        1
    "commentary on how this works: since 0 is falsy and every other number is
     truthy, we can simply subtract two values to determine whether they are
     *un*equal. then we apply a boolean NOT with the method described above"
return

label val
    set _ unwrap slice input _ add 1 _ 1  "basically 'input[_]'"
return

(This is the first real Macaroni program (that actually does something)! \o/)

C# 6, 18 + 67 = 85 bytes

Requires this using statement:

using System.Linq;

The actual method:

string U(string s)=>string.Concat(s.Where((x,i)=>s.IndexOf(x)==i));

This method saves some chars by defining the function as a lambda, which is supported in C# 6. This is how it would look in C# pre-6 (but ungolfed):

string Unique(string input)
{
    return string.Concat(input.Where((x, i) => input.IndexOf(x) == i));
}

How it works: I call the Where method on the string with a lambda with two arguments: x representing the current element, i representing the index of that element. IndexOf always returns the first index of the char passed to it, so if i is not equal to the first index of x, it's a duplicate char and mustn't be included.

AutoIt, 107

Func _($0)
$1=''
For $2 In StringSplit($0,'',3)
$1&=StringInStr($1,$2,1)?'':$2
Next
Return $1
EndFunc

Call it like any function:

ConsoleWrite(_("Type unique chars!"))

CJam, 3 bytes

qL|

Setwise or of the input with an empty list. CJam set operations preserve element order.

Try it online