g | x | w | all
Bytes Lang Time Link
013Perl 5 + plF220719T130729ZDom Hast
030JavaScript230331T140521ZToban Ha
004Japt g¡230331T090130ZShaggy
035Forth gforth241016T193856Zreffu
005Uiua241015T201213ZAdelie
030Red241016T104123ZGalen Iv
012Regex GNU ERE or better230331T204645ZDeadcode
009Regex fullmatch Java / Boost / Python / PCRE2220803T190515ZSeggan
032PowerShell230331T154650ZJames Fl
006Stax230329T135636Zemirps
049Go230329T141551Zbigyihsu
040C++ gcc170514T073353Zjdt
005MATL170513T171419ZSuever
048brev220818T131346ZSandra
046PHP220817T140311ZRam Chan
038Dart220817T101126Zlrn
021C#220803T102130ZAcer
046Swift170514T160242ZLeena
014Jellyfish220803T200437ZDLosc
020Knight220803T065321ZBubbler
010K ngn/k220719T131622Zoeuf
027MUMPS220719T165348ZRyan Pat
003Vyxal220705T151317ZnaffetS
00305AB1E legacy220705T091503ZKevin Cr
013Zsh220705T060835Zpxeger
022Julia220705T055011ZCzylabso
027Lexurgy220126T175734Zbigyihsu
012K ngn/k220126T145712Zcoltim
003BRASCA220126T092452ZSjoerdPe
006Ly220126T073245Zcnamejj
020Labyrinth200929T024304ZBubbler
2585Mornington Crescent200929T082505ZDorian
029MAWP200929T033902ZRazetime
028MAWP 2.0200929T040252Zlyxal
024PowerShell200120T185824ZGMills
006Burlesque200120T181747ZDeathInc
007GolfScript200120T130544Zuser8505
004Brachylog190309T085523ZUnrelate
3634Excel VBA170516T054941ZTaylor R
059Tcl180326T101533Zsergiol
023jq180329T095308Zmanatwor
011><>180329T091204ZJo King
036SmileBASIC 3180329T081447Zsnail_
nanR180327T082002ZRiccardo
033Google Sheets170521T160150ZTaylor R
004Husk180328T003042ZSophia L
nan170514T180148ZBrad Gil
029Julia 0.6180327T095326Zniczky12
4957ActionScript 2.0180326T192404ZJhynjhir
029SmileBASIC180326T184507Z12Me21
034Tcl180326T115422Zsergiol
045C gcc180326T163134ZJonathan
030Vim180326T135841Zoktupol
036C170513T201848ZMD XF
046Casio Basic170515T114110Znumberma
024shortC170513T203132ZMD XF
024Python 2170513T172001ZAdnan
008J170513T172106ZLeaky Nu
020Cubix170612T204211ZGiuseppe
018q/kdb+170528T093543Zmkst
nanPerl 5170516T074250ZChris
017Ruby170519T190756ZValue In
025PowerShell170522T115448Zcolsw
024Python 3170515T141401ZAvahW
033><>170517T041412ZAGourd
019JavaScript170514T191346ZBald Ban
2734Clojure 21170517T183131ZNikoNyrh
030Powershell170520T083129ZAndrei O
012J170519T165713ZCyoce
017TIBasic TI84 Plus CE170520T044534Zpizzapan
030Axiom170519T172730Zuser5898
nanChip170519T162325ZPhlarx
024Ruby170515T134217Zmarmelad
032REXX 32 Bytes170516T134357Ztheblitz
027Golang170516T070830Zersinaky
040R170514T183909Zdjhurio
010Actually170515T210936Zuser4594
055BrainFlak170515T205636ZDJMcMayh
nan170515T031001Zuser1893
042PowerShell170515T202203Zgoric
028Perl 5170515T164826ZTom Tann
025JavaScript ES6170513T171457ZShaggy
051BrainFlak170515T163239ZRiley
077Java170514T092414ZKhaled.K
030C#170514T084233ZTheLetha
004APL Dyalog170513T200310Zuser4180
034C170515T064501Zjdt
029Java 8170515T080050ZKevin Cr
009Pyth170514T213735Zclapp
004Fireball170513T171000ZOkx
037Bash170514T160814ZIt Guy
023PHP>=7.1170513T170757ZJör
020Ruby170514T032004ZKaia Lea
052Batch170514T114159ZNeil
051Python170514T091551Zuser6927
012Retina170513T170642ZNeil
038Excel170514T083318Zqoou
034AWK170513T195436Zshadowta
021Haskell170514T043918ZØrj
058Common Lisp170513T184657Zshadowta
006Japt170513T175037ZLuke
043brainfuck170513T195803ZNitrodon
081S.I.L.O.S170513T190554ZLeaky Nu
006CJam170513T175802Zaditsu q
020JavaScript170513T170304ZArjun
00405AB1E170513T182729ZRiley
023Python 3170513T173934ZDennis
054Standard ML170513T174232Zmusicman
011QBIC170513T175513Zsteenber
012GNU grep170513T173643Zeush77
031Python170513T172059ZErik the
035Python 2170513T172459Ztotallyh
015Mathematica170513T173700ZJungHwan
016Octave170513T171904ZStewie G
003Jelly170513T170617ZErik the
004Brachylog170513T170658ZFatalize

Perl 5 + -plF, 13 bytes

Saved 2 bytes thanks to @Xcali!

$_&&=/$F[0]$/

Try it online!


Perl 5 + -plF/^(.|(.).*\2)$/, 7 bytes

If we abuse -F to perform the pattern matching, @F can be checked directly too see if it contains > 1 entry.

$_=@F>1

Try it online!

JavaScript, 30 bytes

i=>!!(i[0]===i[i.length-1]&&i);

Japt -g¡, 5 4 bytes

é ä¶

Try it

é ä¶     :Implicit input of string
é        :Rotate right
  ä      :Consecutive pairs reduced by
   ¶     :  Equality check
-g       :Implicit output of first element
-¡       :  as a Boolean (to cover the empty string, which would return undefined otherwise)

Forth (gforth), 35 bytes

: f tuck over c@ -rot + 1- c@ = * ;

Try it online!

Explanation

Longest part was handling of empty strings, since there's a small semi-random chance that the char at memory address -1 of an empty string will be the same as the char at the memory address of the string. Solution was just to multiply result by string length, since anything other than 0 is truthy in forth.

Code Explanation

: f         \ start word definition
  tuck      \ save string length
  over c@   \ get first char of string
  -rot +    \ move first char back and add mem address + length
  -1 c@     \ subtract 1 and get char at ending address
  =         \ check if the values are equal
  *         \ multiply by string length to filter out empty strings
;           \ end word definition

Uiua, 8 5 bytesSBCS

-2 bytes from Unrelated String, minus 1 more by me

A function which returns 0 for truthy values and 1 for falsey values. Try it online!

±⍣⊣1⊛

I'd still like to believe this is one of the first times that a try...catch has been utilized in code golf; I rarely even see those on here.

NOTE: At the time of writing this on version 0.13.0-rc.3 (according to the Uiua website), ⊣ last is an experimental function. You can enable experimental features in Uiua by starting your program with an # Experimental! comment. Read more about them here.

Explanation

±⍣⊣1⊛ # main bind
    ⊛ # assign a unique index to each character
 ⍣⊣   # try to get the last index
   1  # if that would throw an error, just push 1
±     # numerical sign

In the case of an empty string, Uiua is unable to get the first or last element of it, because it is of length 0, an empty set. Thus, Uiua throws an error. But since by the time it does so it's already in the try function, so we consult the function to the right of it, which just pushes a 1.

Funnily enough, this works on any value, not just strings exclusively.

Red, 30 bytes

func[s][all[s/1 s/1 = last s]]

Try it online!

Regex (GNU ERE or better), 12 bytes

^(.)(.*\1)?$

This regex was already used in the following answers, shown in chronological order:

  1. eush77's 12 byte GNU grep answer (GNU ERE / PCRE)
  2. Neil's edited 12 byte Retina answer (.NET)
  3. Kevin Cruijssen's 29 byte Java 8 answer (Java)
  4. Shaggy's edited 25 byte JavaScript answer (ECMAScript)
  5. Tom Tanner's 28 byte Perl answer (Perl)
  6. oktupol's 30 byte Vim answer (GNU ERE)
  7. sergiol's edited 34 byte Tcl answer (Tcl ARE)

But here it is demonstrated in the form of a pure regex, in a wider variety of regex engines:

Try it online! / Attempt This Online! - GNU ERE
Try it online! / Attempt This Online! - Tcl ARE
Try it online! - ECMAScript (SpiderMonkey)
Try it online! / Attempt This Online! - ECMAScript 2018 (Node.js)
Try it online! / Attempt This Online! - Perl
Try it online! / Attempt This Online! - Java
Try it online! - Boost
Try it online! / Attempt This Online! - Python
Try it online! / Attempt This Online! - Ruby
Try it online! / Attempt This Online! - PCRE
Try it online! - .NET

^       # Anchor to start of string
(.)     # \1 = Consume one character
(       # Begin grouped expression
    .*      # Skip any number of characters, minimum zero
    \1      # Consume a character if it matches the one captured in \1,
            # otherwise fail to match.
)?      # Evaluate the above group optionally; if it fails to match, it will
        # be skipped.
$       # Assert that we've reached the end of the string

See also Seggan's answer, in which a feature is used that is not present in all regex engines, allowing that regex to be just 9 bytes (the regex is matched against only the entire string, and doesn't attempt substring matches).

Regex (ECMAScript or better), 13 bytes

^(?=(.)).*\1$

Try it online! - ECMAScript (SpiderMonkey)
Try it online! / Attempt This Online! - ECMAScript 2018 (Node.js)
Try it online! / Attempt This Online! - Perl
Try it online! / Attempt This Online! - Java
Try it online! - Boost
Try it online! / Attempt This Online! - Python
Try it online! / Attempt This Online! - Ruby
Try it online! / Attempt This Online! - PCRE
Try it online! - .NET

Doesn't beat the 12 byte version in golf or in range of compatibility (GNU ERE isn't supported due to lack of lookaheads, and Tcl ARE isn't supported due to lack of support for captures or backreferences inside lookaheads), but included anyway, to demonstrate another method that's rather elegant.

Already used in Neil's original 13 byte Retina answer before being edited down to 12 bytes.

^         # Anchor to start of string
(?=       # Lookahead
    (.)   # \1 = one character
)
.*        # Skip any number of characters, minimum zero (if more than zero
          # characters are skipped, the first of them will be the one captured
          # in the lookahead above)
\1        # Consume a character if it matches the one captured in \1,
          # otherwise fail to match.
$         # Assert that we've reached the end of the string

Regex fullmatch (Java / Boost / Python / PCRE2), 11 9 bytes

(.).*\1|.

Try it online! / Attempt This Online! - Java
Try it online! - Boost
Try it online! / Attempt This Online! - Python
Try it online! / Attempt This Online! - PCRE2

Simple non-complicated regex. Would have been even less complicated if not for the fact that you had to match single char strings. Matches a string only if the first and last characters are equal.

(.).*\1|.  # The regex
     \1    # Does the last character equal...
(.)        # The first character?
   .*      # Allow anything in between
       |.  # Or match a string 1 character in length

PowerShell, 32 bytes

if($a){return $a[0]-ceq$a[-1]}!1

Try it online!

Stax, 6 bytes

¢₧/#HL

Run and debug it

This is a function which takes input as a string.

This is PackedStax which unpacks to the following 7 bytes:

%_:EE=I

Run and debug it

Explanation

%     I # input length is > 0 and
 _:E    # input string first and last value
    E=  # are equal

Go, 50 49 bytes

func(s string)bool{return""<s&&s[0]==s[len(s)-1]}

Attempt This Online!

C++ (gcc), 40 bytes

[](auto s){return s[0]&&s[0]==s.back();}

Try it online!

MATL, 5 bytes

&=PO)

Try it at MATL Online!

Explanation

       % Implicitly grab input as a string (of length N)
&=     % Perform an element-wise equality check yielding an N x N matrix
P      % Flip this matrix up-down
O)     % Get the last value in the matrix (column-major ordering)
       % Implicitly display the result

In the case, that an empty input string must be handled, then something like the following (8 bytes) would work

&=POwhO)

This solution simply prepends a 0 to the front of the N x N matrix such that for an empty input, when the matrix is 0 x 0, there's still a 0 value that is then grabbed by 0)

Try it at MATL Online

brev, 48 bytes

(as-list(fn(if(null? x)#f(eq?(car x)(last x)))))

Examples:

(map (as-list(fn(if(null? x)#f(eq?(car x)(last x)))))
     '("10h01"
       "Nothing"
       "Acccca"
       "eraser"
       "erase"
       "wow!"
       "wow"
       "H"
       ""))

The null check adds a lot! 💔

PHP, 46 bytes

$f=fn($x)=>fn($y)=>($x==$y&&($y!=""))?'T':'F';

Try it online!

Dart, 38 bytes.

c(s)=>s.length>0&&s[0]==s[s.length-1];

Nothing amazing. Introducing a variable for s.length takes one character more. Splitting an empty string, or using s.runes/s.charCodes, gives an empty list, which needs special casing anyway.

C#, 25 21 bytes

Uses the index operator ^ from C# 8 to get the last character in the string.

x=>x!=""&&x[0]==x[^1]

Try it online!

-4 bytes thanks to the default

Swift, 46 bytes

var s=readLine()!,a=Array(s);a[0]==a.last ?1:0

Jellyfish, 14 bytes

P
=<,1
v
, I
2

Try it online! (The input requires a trailing newline to handle the empty string case correctly.)

Explanation

A straightforward solution would be 7 bytes if we didn't have to handle empty strings:

P
=<
vI

I inputs a string, which goes to both < (first element) and v (last element). The results of both of these functions go to =, and the comparison result gets printed by P.

However, < and v error when the string is empty, so we have to add some workarounds. Note that strings in Jellyfish are lists of characters, and lists can contain values with different data types.

<,1

 I

Append 1 to the input and take the first element: either a character, or 1 if the input was empty.

v
, I
2

Prepend 2 to the input and take the last element: either a character, or 2 if the input was empty.

P
=

Compare and print the result, as before.

Knight, 20 bytes

O<!=xP?AxA Gx-Lx 1 1

Try it online!

Takes a line from stdin and prints true if equal and false otherwise.

O                           Output the result of:
  < ! (= x P)                 x = input; x is not null and
    ? A x                       the first char's ord is equal to
      A (G x (- L x 1) 1)       the (length-1)th char's ord

K (ngn/k), 16 15 10 bytes

{0^*|x=*x}

Try it online!

-5 bytes thanks to ngn!

MUMPS, 27 bytes

 w x]""&($e(x)=$e(x,$l(x)))

Try it online!

It could be further reduced to 23 bytes in Intersystems Caché/IRIS by replacing $l(x) with *.

 w x]""&($e(x)=$e(x,*))

Vyxal, 3 bytes

Ṙ=h

Try it Online!

Input as a list of chars.

05AB1E (legacy), 3 bytes

Ć`Q

Try it online or verify all test cases.

Explanation:

Ć    # Enclose the (implicit) input-string; append its own head
 `   # Pop and push all characters separated to the stack
  Q  # Check if the top/last two are the same
     # (after which the result is output implicitly)

The empty test case only works in the legacy version of 05AB1E, because Q on an empty stack and without input is apparently falsey. Whereas in the new version of 05AB1E an empty input is interpret as an empty string, in which case ""=="" is truthy.

Zsh, 13 bytes

>_$1<*${1[1]}

Attempt This Online!

Julia, 22 bytes

!s=s>""&&s[1]==s[end]   

Attempt This Online!

Lexurgy, 27 bytes

a:
([]$1) []* !$1=>*
[]+=>a

Outputs an empty string for falsey, and a otherwise.

Explanation:

a:                # change...
([]$1)            # the first character
       []*        # then 0 or more any character, regex /.*/
           !$1    # then a character that's not the first
              =>* # change to an empty string
# equivalent regex: /(.).*\1/
[]+=>a            # replace the leftovers with "a"

K (ngn/k), 12 bytes

{0^*(*x)=|x}

Try it online!

A port of @user41805's APL answer.

BRASCA, 3 bytes

This looks like a job for M!

M=n

Try it online!

Explanation

M        - Move the bottom of the stack to the top
 =       - Are they the same? Push 1 if it is, 0 if it isnt.
  n      - Output as number.

Ly, 6 bytes

i0I=u;

Try it online!

One caveat about this one... Ly can't detect null input, so it doesn't handle that use case.

i       - read STDIN onto the stack a codepoints
 0I     - copy the bottom of stack to the top
   =    - compare top two entries on the stack
    u   - print the result
     ;  - exit to avoid print the rest of the stack

Labyrinth, 27 20 bytes

,)!@
 : !
,} _
")=-:

Try it online!

-7 bytes thanks to Jo King.

Basic flow goes like this: start at the upper left corner, filter away the empty input at the first T-junction, take the rest of the string at the 2x2 loop, and test for equality at the last T-junction.

How it works

x marks the alternative paths at junctions, which should make the explanation easier to follow.

,)!@   Take char input (possibly EOF == -1), increment
 x     If EOF, top is 0, so go straight, print 0 and halt

 x     Otherwise, the string is not empty
 :     Duplicate the first char and move to aux. stack
,}     Go around the 2x2 loop `,")}`:
")x    Take next char input, increment, move to aux. stack
       until it hits EOF, where the stack is [first 0 | last ... first]
  @
  !    `=`: Swap the top of two stacks, giving [first last | (ignored)]
  _    Then calculate first - last
x=-x   If nonzero, take the north branch `_!@`: Push 0, print, halt

x)!@
 :     If zero, go all the way back to the first branch
x} x   (Eventually print 1 and halt)
x)=-:

Mornington Crescent, 2585 bytes

Take Northern Line to Bank
Take Circle Line to Hammersmith
Take District Line to Mile End
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Victoria
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Hammersmith
Take District Line to Bow Road
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Barking
Take District Line to Hammersmith
Take District Line to Mile End
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank
Take Circle Line to Bank
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Upminster
Take District Line to Temple
Take District Line to Barking
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Barking
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Bank
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Angel
Take Northern Line to Bank
Take Circle Line to Temple
Take District Line to Bow Road
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Bow Road
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Angel
Take Northern Line to Bank
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

Try it online!

I thougt, this was easier...

Outputs 0 for false and 1 for true

// Prepare input for right substring
Take Northern Line to Bank
Take Circle Line to Hammersmith
Take District Line to Mile End

// Get char code of first character
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross

// Put it in Upminster for later calculation
Take Northern Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster

// Also save it for later check for null string # Victoria = char code of first
Take District Line to Hammersmith
Take Circle Line to Victoria

// Save 0 # Upney = 0, Bow Road = 0 (for second loop)
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Hammersmith
Take District Line to Bow Road

// Save 1 # Barking = 1
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Barking

// Get char code of last letter of input
Take District Line to Hammersmith
Take District Line to Mile End
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross

// Bitwise NOT, so we get -(char count)-1
Take Northern Line to Bank
Take Circle Line to Bank
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate

// Add it to the char code of first letter. If they match, the result is -1.
Take District Line to Upminster

// Save the result in Upminster
Take District Line to Upminster

// ********************************************************************************
// * Add some logic. This is quite puzzling because the only control structure    *
// * in Mornington Crescent is a post-test loop. You don't have something like    *
// * an if-else. You can't skip code. You can only define how often a loop should *
// * be repeated.                                                                 *
// * My solution to this is: When checking if the first and last character        *
// * are the same (first char code - last char code = 0), I swap the positions    *
// * of the 0 and 1 variables, then multiply the result of the equality check     *
// * with the new position of 1. If the characters are the same, the loop will    *
// * exit after the first run. If not, it will run another time, swapping the     *
// * 0 and 1 back and exiting after the second run, because it multiplies the     *
// * new equality check with 0.                                                   *
// ********************************************************************************

// Set starting line of loop
Take District Line to Temple

// Swap 0 and 1 # Upney = 1, Barking = 0 (on the first run)
Take District Line to Barking
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Barking

// Save 1 in Chalfont & Latimer for later multiplication
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer

// Add 1 to Upminster, to check for equality
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster

// Multiply the result with 1 in the first run, or 0 in the second run
Take District Line to Bank
Take Circle Line to Bank
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer

// If the result is not 0, run the loop again
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Angel

// **********************************************************************
// * Another control loop to check for empty string.                    *
// * The previous loop will return true if an empty string was entered. *
// **********************************************************************

// Set start of loop
Take Northern Line to Bank
Take Circle Line to Temple

// Swap 0 and 1 # Upney = 0, Bow Road = 1 (on the first run, if previous loop ran once)
//              # Upney = 0, Bow Road = 0 (if previous loop ran twice)
Take District Line to Bow Road
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Bow Road

// store 1 in Chalfont & Latimer for later multiplication
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer

// Multiply by char code of first char (0 if empty string)
Take Metropolitan Line to Aldgate
Take Circle Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer

// Loop again if input not empty
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Angel

// Fetch result and go home for output
Take Northern Line to Bank
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

MAWP, 21 29 bytes

|1A<1:.>1M\%_1A<1:.>\A{0:.}1:

Try it!

Fixed for empty input(and single character input, after Lyxal pointed out). If input is empty, it checks if the existing 1 on the stack is still at the top. then checks the length of the input.

MAWP 2.0, 28 bytes

=A|_!=W1-W0-*{`=M~M-{0=A}}A:

Try it!

PowerShell, 24 bytes

!("$args"[0,-1]|gu).Rank

Try it online!

Burlesque, 6 bytes

l_-]==

Try it online!

l_ # Non-destructive tail, leaving the rest of the string on top of the stack
-] # Destructive head
== # Equal

GolfScript, 7 bytes

)\(@=\;

Try it online!

Explanation

)       # The last character
 \(     # And the first character
   @=\; # Are they equal

Brachylog, 4 bytes

h.&t

Try it online!

and

Brachylog, 4 bytes

h~t?

Try it online!

are both predicates which try to unify the first and last elements of the input, outputting through success or failure (which prints true. or false. when it's run as a program).

Excel VBA, 52 48 40 38 37 36 34 Bytes

Anonymous VBE immediate window function that takes input of type variant and expected type variant\String from cell [A1] on the ActiveSheet object and outputs boolean response to the VBE immediate window.

?[A1]<>""=([Left(A1)]=[Right(A1)])

Tcl, 59 bytes

proc C s {expr {[string in $s 0]==[string in $s e]&$s!=""}}

Try it online!

jq, 23 characters

(20 characters code + 3 characters command line option)

.>""and.[:1]==.[-1:]

Sample run:

bash-4.4$ jq -R '.>""and.[:1]==.[-1:]' <<< $'10h01\nNothing\nAcccca\nwow!\nwow\nH\n'
true
false
false
false
true
true
false

Try it online!

jq, 25 characters

(22 characters code + 3 characters command line option)

endswith(.[:1])and.>""

Just to show that jq also has endswith() function. But unfortunately all strings are considered to end with empty string, so is not shorter. ☹

><>, 11 bytes

l?!<{:}=n;!

Try it online!

Takes input through the -s flag. You'll need to remove the flag for an empty input.

How it works

l?!<  Go right if there is input, left is there is none
    {:  If there is input, rotate the stack and dupe the first element
        This creates two copies of a one character input
      }=n;  Print if the last character is equal to the first
l  If there is no input, push the length of the stack (0)
        n;!  Wrap around and print the 0

SmileBASIC 3, 36 bytes

In SmileBASIC, 0 is false and 1 (or nonzero) is true.

LINPUT S$L=LEN(S$)?L&&S$[0]==S$[L-1]

Explainer:

 LINPUT S$                'read line from console to string S$
 L=LEN(S$)                'store length of line in L
 ? L && S$[0] == S$[L-1]
'| |          |
'| |          \-----------first char equals last char
'| \----------------------length is false if zero, && shortcuts
'\------------------------print

R, 50 43 41 40 64

Second solution with 41 bytes for a callable function - thanks to @niczky12 & @Giuseppe - amended for x=""

r=function(x,y=utf8ToInt(x))ifelse(x=="","FALSE",(y==rev(y))[1])

First with 50 bytes but not for the challenge

function(x){charToRaw(x)[1]==rev(charToRaw(x))[1]}

Google Sheets, 33 Bytes

Takes input from cell [A1] and outputs 1 for truthy input and 0 for falsey input.

=(A1<>"")*Exact(Left(A1),Right(A1

It is noted that the parentheticals in Exact( and Right( are left unclosed as Google Sheets automatically corrects this as soon as the user has input the formula text and pressed enter to leave that cell.

Output

GS Version

Husk, 4 bytes

Γ·=→

Try it online!

Takes a string as an argument to the program, returns 0 for falsy cases and 1 for truthy cases.

Explanation:

Γ is list deconstruction. The version I'm using (listN) takes a binary function and returns a function that takes a list. This new function returns the default type (0 in this case) for an empty string, and otherwise applies the given function to the head and tail of the string. The binary function I'm giving it is = (equality), composed on the second argument (·) with (last element of a list).

Perl 6,  18  17 bytes

{?m/^(.)[.*$0]?$/}

Test it

{?/^(.)[.*$0]?$/}

Test it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  ?        # Boolify the following

  /        # match implicitly against 「$_」


    ^      # beginning of string

    (.)    # character 「$0」

    [

      .*   # followed by any number of characters
      $0   # and itself

    ]?     # optionally (Str with a single char)

    $  # end of string
  /
}

Julia 0.6, 29 bytes

f(x)=x==""?false:x[1]==x[end]

Try it online!

ActionScript 2.0, 49 57bytes

function a(b){trace(b!=""?b.substr(0,1)==b.slice(-1):0);}

Old version (v) doesn't output false for "", but the new, longer version does.

function a(b){trace(b.substr(0,1)==b.slice(-1));}

I'm fairly sure this is the shortest way to do it, but...

The semicolon can be removed and it'll still compile in JPEXS.

This is a pretty simple function - if the argument is not "", output whether the (0, 1) substring of the argument (basically a way of getting the first character) is equal to the last character, obtained by slicing the string at its last character, otherwise 0. Tracing is shorter than returning.

SmileBASIC, 29 bytes

DEF E S?S>""&&POP(S)==S[0]END

Pretty simple, but it's important that the POP is done after the first character is checked, so it will work on 1 character long strings.

Tcl, 34 bytes

proc C s {regexp ^(.)(.*\\1)?$ $s}

Try it online!

C (gcc), 45 bytes

f(s,j)char*s;{for(j=*s;*s;s++);j=j&&j==*--s;}

Try it online!

Vim, 30 bytes

:s/\v^(.)(.*\1)?$/1
:s/^..\+/

Leaves you with 1, if the string starts and ends with the same character, or nothing, if it doesn't.

C, 50 40 36 bytes

Saved 10 bytes thanks to Dennis.

#define f(s)(*s&&*s==s[strlen(s)-1])

Equates to 0 if the first and last characters are different, or if the string is empty.

You could call f with something like:

int main(void)
{
    char s[100] = {0};
    gets(s);
    printf("%d\n",f(s));
}

Or, try it online!

Casio Basic, 46 bytes

StrLeft s,1,a
StrRight s,1,b
Print judge(a=b)

Strings aren't very nice to work with in this language. We need to take the first character from the left and right of the string, assign them to a and b, then print whether a is equal to b.

45 bytes for the code, 1 byte to enter s as parameter.

shortC, 27 26 25 24 bytes

f(C*s){T*s&&*s==s[Ss)-1]

How it works:

f(C*s){                     declare int-returning function that takes a string
       T                    return
        *s                  provided string has any length
          &&                and
            *s==s[Ss)-1]    the first character equals the last one

Try it online!

Python 2, 26 25 24 bytes

Thanks to @Dennis for saving a byte!

lambda x:""<x[:1]==x[-1]

Try it online!

J, 8 bytes

1 byte thanks to Kritixi Lithos.

1{.{.=|.

Try it online!

Cubix, 20 bytes

@O0UA?n\.\1.1\2ntc?U

Returns 0 for false and 1 for true.

Cubified:

    @ O
    0 U
A ? n \ . \ 1 .
1 \ 2 n t c ? U
    . .
    . .

explanation:

A - read in input as chars; so input of abc has the stack -1,99,98,97
? - turn left if negative (empty string), right if positive
if negative:
   0 - push 0
   U - left u-turn
   O - output as int
   @ - end program
if positive:
\ - reflect so we are moving to the right
2 - push 2
n - negate top of stack 
t - pop top of stack, move that item from the bottom to the top; moves the last character to top of stack
c - xor
? - turn right if positive, go straight if negative
if 0:
   U - left U-turn
   1 - push 1
   \ - reflect so we point up
   O - output 1
   @ - end program
if positive
   n - negate
   \ - reflect
   n - negate
   ? - righthand turn
   0 - push 0
   U - lefthand U-turn
   O - output
   @ - end program

Try it online!

Watch it online

q/kdb+, 21 20 18 bytes

Solution:

{#:[x]&(1#x)~-1#x}

Example:

q){#:[x]&(1#x)~-1#x}"abc"
0
q){#:[x]&(1#x)~-1#x}"abca"
1
q){#:[x]&(1#x)~-1#x}""
0

Explanation:

Take the first and last elements of the list, check for equality (return boolean 1 or 0), then check length of string, return the minimum of these two results.

{                } / anonymous lambda function
             -1#x  / take (#) 1 item from end of list
       (1#x)       / take (#) 1 item from start of list
            ~      / are they equal
 #:[x]             / count (#:) length of list x
      &            / minimum

Perl 5, 22+1 (-p flag)=23 bytes

/^(.).*(.)/;$_=$1 eq$2

Outputs 1 for truthy and an empty string for falsey.

Ruby, 16 17 bytes

Outputs true or false. Now with fixed syntax error.

p !! ~/./&~/#$&$/

Try it online!

PowerShell, 25 Bytes

($a="$args")[0]-ceq$a[-1]

gets the first char and last char, performed a case-sensitive comparison of them.

Python 3, 31 24 Bytes

lambda a:a[0]==a[-1]!=''

Old code:

def f(a):return a[0]==a[-1]!=''

This is pretty self explanatory; It takes a string a and checks if the first and last chars are equal, but I then had to add the !='' in order to satisfy the requirement "The input can be empty String as well, for which you should return a falsey value" because Python returns True for an empty string.

EDIT:

  • -7 Bytes thanks to @numbermaniac
  • ><>, 39 33 bytes

     2i&01. >~&-?v1v
      i:1+?!^01. >0>n;
    

    This is my first time both using ><> and playing code golf, so helpful suggestions would be appreciated.

    The code is in three basic sections.

    2i&01. Pushes an arbitrary number (2 in this case, this causes an empty string to print 0) onto the stack and puts the input's first character in the register.
    
    >i:1+?!^01. Main loop. Pushes the next character onto the stack. If the string has been read completely, then go to the last section
    
    >~&-?v1v
         >0>n;  Compare the first and last characters. Print 1 if they're the same, 0 if not
    

    JavaScript, 19 bytes

    a=>a.endsWith(a[0])
    

    Clojure: 21, 27 or 34 bytes

    depending on the handling of "" test case

    true for "aba" and "", false for "abc":

    #(=(first %)(last %))
    

    true for "aba", nil for "", false for "abc":

    #(first(map =(reverse %)%))
    

    true for "aba", nil for "" and "abc":

    #(or(first(map =(reverse %)%))nil)
    

    Powershell, 30 bytes

    "$args"|%{!($_[0]-$_[-1]+!$_)}
    

    Try it online

    J, 12 bytes

    '({.={:)*.*@#
    

    {. means start, = means equals, and {: means end. *.*@# means "logical and with the length of the string", i.e., if the length is 0, it returns 0.

    TI-Basic (TI-84 Plus CE), 17 bytes

    sub(Ans,1,1)=sub(Ans,length(Ans),1
    

    Run with "string":prgmNAME. Returns 1 for true and 0 for false.

    Axiom, 30 bytes

    f(a)==(#a=0=>false;a.1=a.(#a))
    

    this below seems not to be ok

    f(a)==(#a=0=>false;a.#a=a.1)
    

    Chip, 91+3 = 94 bytes

    *Z~.
    ,-{mA
    >{xmB
    |BA|
    |CD|AvB
    >{xmC+G
    >-{mD+H
    >{-mE+~t
    >x{mF^S
    |EF|
    |HG|
    >x{mG
    >{-mH
    Z--)~a
    

    +3 for -z

    Outputs the byte 0x0 for falsey, and 0x1 for truthy. This is a lot bigger than I was hoping, sadly.

    Try it online! (Note about the TIO: it includes an extra line e*f to map the output to ASCII digits. TIO also includes the verbose flag -v, which gives extra debug output via stderr.)

    The first line produces a signal on only the first byte, allowing us to store that byte's bits, and to detect the empty string. (If we could give a truthy value for the empty string, -3 bytes.)

    The last line deals with output, producing truthy only if the first and most recent bytes match, and if it isn't the first byte. Output is given one byte after the end of the input, with the help of -z. If not, we would be unable to detect the end of the string. (If we swapped truthy and falsey, -2 bytes, or if combined with empty string savings above, -4 for the both.)

    The blob to the right, surrounding the +'s, is what triggers the end of input behavior. This actually looks for a zero byte, meaning that incorrect results may occur if one is given as input.

    The remainder of the elements perform the actual comparison. This comparison performed is equivalent to, in C-ish: !(input[0] xor input[n]). In Chip, however, this must be performed for each bit individually, hence the eight sets of memory cells m, xor-gates {, and so on.

    There is an interesting caveat to this implementation, in that it can handle 8 bits, but is unaware of unicode. So, effectively, this compares the first and last bytes, rather than chars.

    Ruby, 26 24 bytes

    Saved two bytes thanks to @philomory!

    ->e{!!e[0]>0&&e[0]==e[-1]}
    

    First post on codegolf -))

    REXX 32 Bytes

    a=arg(1)
    say abbrev(a,right(a,1))
    

    Tests if the last character is a valid abbreviation of the whole string.

    Golang, 27 bytes

    if n[0:1] == n[(len(n))-1:]
    

    Full Program

    package main
    import (
        "fmt"
    )
    func f(x string) string {
        if x[0:1] == x[(len(x))-1:] {
            return "Truthy"
        } else {
            return "Falsey"
        }
    }
    func main() {
        var n string
        fmt.Scanf("%q", &n)
        fmt.Printf("%q", f(n))
    }
    

    Try it online!

    R, 40 bytes

    function(x)x>""&&rev(y<-charToRaw(x))==y
    

    Thanks to Nitrodon for -2 bytes.

    Thanks to MickyT for -8 bytes.

    Test:

    f=function(x)x>""&&rev(y<-charToRaw(x))==y
    test <- c("10h01", "Nothing", "Acccca", "wow!", "wow", "H", "")
    sapply(test, f)
    all(sapply(test, f) == c(T, F, F, F, T, T, F))
    

    Output:

    > f=function(x)x>""&&rev(y<-charToRaw(x))==y
    > test <- c("10h01", "Nothing", "Acccca", "wow!", "wow", "H", "")
    > sapply(test, f)
      10h01 Nothing  Acccca    wow!     wow       H         
       TRUE   FALSE   FALSE   FALSE    TRUE    TRUE   FALSE 
    > all(sapply(test, f) == c(T, F, F, F, T, T, F))
    [1] TRUE
    

    Actually, 10 bytes

    ;;lb)F@N=*
    

    Try it online!

    Explanation:

    ;;lb)F@N=*
    ;;          copy input twice
      lb        length of input, cast to boolean
        )F      first character
          @N    last character
            =   compare equality
             *  multiply by boolean casted length (to make empty strings falsey)
    

    Brain-Flak, 55 bytes

    (({})<(())>)({}[<{({}<>)<>}><>{}]<>)((){[()](<{}>)}{})
    

    Try it online!

    Java, 52 43 bytes

    s->!s.isEmpty()&&s.endsWith(""+s.charAt(0))
    

    To make it work, feed this into a function such as the following that makes a lambda "go":

    private static boolean f(Function<String, Boolean> func, String value) {
      return func.apply(value);
    }
    

    PowerShell, 42 bytes

    $a=(read-host);$a-ne""-and$a[0]-ceq$a[-1]
    

    Perl 5: 28 bytes

    exit$ARGV[0]=~/^(.)(.*\1)?$/
    

    Similar to perl 6 but it seems to be shorter as a program.

    JavaScript (ES6), 25 bytes

    s=>/^(.)(.*\1)?$/.test(s)
    

    21 bytes if we can return true for the empty string.

    s=>s[0]==[...s].pop()
    

    Try it

    f=
    s=>/^(.)(.*\1)?$/.test(s)
    o.innerText=f(i.value="10h01")
    i.oninput=_=>o.innerText=f(i.value)
    <input id=i><pre id=o>

    Brain-Flak, 51 bytes

    Includes +1 for -a

    {(<([({})<{({}<>)<>}<>>]{})((){[()](<{}>)}{})>)}{}
    

    Try it online!

    Outputs 1 on top of the stack for truthy, and either nothing or 0 on top of the stack for falsy. These are consistent with Brain-Flak's "if" statement: {...}.

    {(<                                          >)}{} # If there is input...
         ({})<            >                            #   Evaluate to the first char after...
              {({}<>)<>}<>                             #     reversing the entire stack
       ([                  ]{})((){[()](<{}>)}{})      # Check if the top 2 are equal
                                                       # I.e. first == last
    

    Java, 81 77 bytes

    Try Online

    boolean f(String s){int l=s.length();return l>0&&s.charAt(l-1)==s.charAt(0);}
    

    Array Version, 60 bytes

    boolean f(char[]s){int l=s.length;return l>0&&s[0]==s[l-1];}
    

    C#, 38 30 bytes

    s=>s!=""&&s[0]==s[s.Length-1];
    

    Saved 8 bytes thanks to @raznagul.

    APL (Dyalog), 4 bytes

    ⊃⌽=⊃
    

    Try it online!

    Explanation

      =                     Compare
       ⊃                    The first element of the right argument with
     ⌽                      The right argument reversed
                            This will return an array of the length of the reversed argument. Each element in the resulting array will be either 0 or 1 depending on whether the element at that position of the reversed argument equals the first element of the original right argument
                            So with argument 'abcda', we compare 'a' with each character in 'adcba' which results in the array 1 0 0 0 1
    ⊃                       From this result, pick the first element.
    

    Here is the reason this works on empty strings. Applying to an empty string returns a space . But reversing an empty string still returns an empty string, so comparing an empty string with a non-empty string (in this case ) gives an empty numerical vector. And applying to an empty numerical vector returns 0. Hence passing an empty string returns 0.

    C, 34 bytes

    f(char*s){s=*s&&*s==s[puts(s)-2];}
    

    Try it online

    C, 35 bytes

    f(char*s){s=*s&&!strrchr(s,*s)[1];}
    

    Try it online

    Java 8, 29 bytes

    s->s.matches("^(.)(.*\\1)?$")
    

    Port of @Neil's Retina answer.

    Try it here.

    Pyth, 9 bytes

    .xqhzez!1
    

    Try it online!

    Could make it 5 bytes if I didn't have to deal with "", probably even less if I was good at Pyth.

    Fireball, 4 bytes

    d1╡├
    

    Explanation:

    d      Duplicate implicit input
     1╡    Get the first character
       ├   Check whether the input ends with the first character
    

    Alternative program:

    d↔♥├
    

    Bash, 37 bytes

    [ -n "$1" ]&&[ ${1:0:1} == ${1: -1} ]
    

    Takes command line input and returns with exit status 0 (truthy) or 1 (falsy).

    Test with:

    bash test.sh "helloH" ; echo $?
    

    PHP>=7.1, 23 Bytes

    prints 1 for equal and nothing if the character is different

    <?=$argn[0]==$argn[-1];
    

    Ruby, 22 20 bytes

    ->x{x[0]===x[-1]||p}
    

    Batch, 52 bytes

    @set s=!=
    @set/ps=
    @if "%s:~,1%"=="%s:~-1%" echo 1
    

    Outputs 1 if equal, nothing if not. set/p doesn't change the variable if nothing is entered, so I can initialise it to a failure case, and != seemed appropriate.

    Python, 51 bytes

    s=input()
    if s:print(s[0]==s[-1])
    else:print(False)
    

    Try it online!

    Retina, 13 12 bytes

    ^(.)(.*\1)?$
    

    Try it online! Includes test suite. Edit: Saved 1 byte thanks to @Kobi.

    Excel, 38 bytes

    =1*IFERROR(CODE(A1)=CODE(RIGHT(A1)),0)
    

    Surprisingly longer than I expected, in order to get the same truthy/falsy for all cases. Text conditionals ignore case by default in excel, so "A"="a" is TRUE. Empty cells yield an error for CODE(). Multiplied by 1 to force everything to a number, rather than having TRUE, FALSE, or 0 cases.

    AWK, 29 34 bytes

    This one might be cheating slightly, because it requires invoking AWK with the option:

    `-F ''`
    

    In GNU Awk you can use the long-form synonyms:

    `--field-separator=''`
    

    So I added 5 bytes to the total to account for this.

    Ugly:

    NR==1{a=$1}END{print(a==$NF)}
    

    Pretty:

    NR == 1
    {
        a = $1
    }
    
    END
    {
        print(a == $NF)
    }
    

    Haskell, 21 bytes

    c takes a String and returns a Bool.

    c s=take 1s==[last s]
    

    Try it online!

    Common Lisp, 83 74 61 58 bytes

    Original: 83 bytes

    I've just started learning Common Lisp, so I feel like I'm bringing a putter to a driving range. There must be some kind of recursive macro wizardry or array manipulation possible here that I'm not seeing.

    This is an anonymous function that accepts a string as its input:

    (lambda (s) (let ((n (- (length s) 1))) (when (> n 0) (eq (char s 0) (char s n)))))
    

    Prettified:

    (lambda (s)
      (let ((n (- (length s) 1)))
        (when (> n 0)
          (eq (char s 0)
              (char s n)))))
    

    Would love to see a slicker solution!

    Revision 1: 74 bytes

    Gotta love those standard library functions!

    Ugly:

    (lambda (s) (when (> (length s) 0) (eq (elt s 0) (elt (reverse s) 0))))
    

    Pretty:

    (lambda (s)
      (when (> (length s) 0)
        (eq (elt s 0)
            (elt (reverse s) 0))))
    

    Revision 1.5: 61 bytes

    Whitespace!

    (lambda(s)(when(>(length s)0)(eq(elt s 0)(elt(reverse s)0))))
    

    Revision 2: 58 bytes

    Ugly:

    (lambda(s)(and(>(length s)0)(not(mismatch s(reverse s)))))
    

    Pretty:

    (lambda (s)
      (and (> (length s) 0)
           (not (mismatch s (reverse s)))))
    

    That's all for now! I think I'm smarter already.

    Japt, 6 bytes

    tJ ¥Ug
    

    Try it online!

    brainfuck, 43 bytes

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

    Try it online!

    Explanation

    The main loop is [>[->+<<->],]. After each iteration, the cell to the right of the current position is the first byte of the string, and the cell to the left is the difference between the most recently handled character and the first. <[[-]-<] converts the final result to -1 if nonzero, and the rest converts -1 and 0 to 48 and 49 ("0" and "1") respectively.

    S.I.L.O.S, 81 bytes

    loadLine
    a=256
    c=get a
    lblb
    t=s
    s=get a
    a+1
    if s b
    t-c
    if t d
    i+1
    lbld
    printInt i
    

    Try it online!

    CJam, 6

    q_W>#!
    

    Try it online

    Explanation:

    q_     read and duplicate the input
    W>     get the substring starting from the last position (W=-1)
            the result is empty if the input is empty
    #      find the position of that substring within the initial string
            a bit surprising, position of empty string within itself is -1 (not found)
    !      negate (0->1, non-zero->0)
    

    Note: I consider the behavior of # with an empty substring to be a bug in CJam⩽0.6.5 and I will probably fix it in the next version. It's useful for this challenge though.

    JavaScript, 20 bytes

    Add f= at the beginning and invoke like f(arg).

    _=>_[0]==_.slice(-1)
    

    f=_=>_[0]==_.slice(-1)
    
    i.oninput = e => o.innerHTML = f(i.value);
    <input id=i><pre id=o></pre>

    Explanation

    This function takes in an argument _. In the function body, _[0]==_.slice(-1) checks whether the first element of _ (at 0th index) equals the last element of it, and returns the appropriate true or false boolean.

    05AB1E, 4 bytes

    S¬Q¤
    

    Try it online! or Try All Tests

    S    # Split the input into individual characters
     ¬   # Get the first character
      Q  # Check all characters for equality to the first
       ¤ # Get the last value i.e. head == tail
    

    Python 3, 23 bytes

    s=input()
    s[0]!=s[-1]<e
    

    Output is via exit code, so 0 (success) is truthy and 1 (failure) is falsy. If this is acceptable, a byte can be saved.

    Try it online!

    How it works

    First of all, if s is an empty string, s[0] will raise an IndexError, causing the program to fail.

    For non-empty s, if the first and last characters are equal, s[0]!=s[-1] will evaluate to False, so the program exits cleanly and immediately.

    Finally, if the characters are different, s[0]!=s[-1] will evaluate to True, causing the compairson s[-1]<e to be performed. Since e is undefined, that raises a NameError.

    If backwards compatibility with Python 2 is not desired,

    s[0]!=s[-1]<3
    

    works as well, since comparing a string with an integer raises a TypeError.

    Standard ML - 52 54 bytes

    open String
    fn s=>s<>""andalso sub(s,0)=sub(s,size s-1)
    

    QBIC, 12 11 bytes

    ?_s;|=_s_fA
    

    Explanation:

    ?              PRINT
         =         -1 if equal, 0 if not, between
     _s;|          QBIC's Substring function takes a variable amount of parameters.
                     With only a string as argument it takes the leftmost char of it.
                     The ; takes a string from the cmd line and names it A$
                     | closes the call to Substring
          _s_fA    _f flips string A, _s without arguments takes the left 1 char again.
    

    Original 12 byter, which takes a substring of 1 from the left and 1 from the right:

    ?_s;|=_sA,-1
    

    Explanation of the second substring:

          _sA,-1   Another call to Substring
                     A$ is implicitly defined by the ; in the other substring
                     -1 sets the starting index at the last position
                     No argument for length = 1 char by default.
                   No closing |, auto-added at EOF
    

    GNU grep, 12 bytes

    ^(.)(.*\1)?$
    

    Run in extended or PCRE mode.

    I don't know if this is considered cheating or not.

    Python, 31 bytes

    lambda x:bool(x)and x[0]==x[-1]
    

    Python 2, 36 35 bytes

    -1 byte thanks to Erik the Outgolfer

    lambda s:s[0]==s[-1]if s else False
    

    Try it online!

    Mathematica, 15 bytes

    #&@@#===Last@#&
    

    Takes an array of chars. Throws errors when the input is empty but can be ignored.

    Octave, 16 bytes

    @(s)s(1)==s(end)
    

    It takes a string s as input, and compares the first s(1) element with the last s(end).

    This could be @(s)s(1)-s(end) if it was OK to swap true/false to false/true.

    Jelly, 3 bytes

    =ṚḢ
    

    Try it online!

    Brachylog, 4 bytes

    h~t?
    

    Try it online!

    Explanation

    h       The head of the Input...
     ~t?    ...is the tail of the Input