Proposal: accept go run -c 'program text here'

324 views
Skip to first unread message

Dan Kegel

unread,
Jul 5, 2026, 9:31:12 PM (4 days ago) Jul 5
to golang-nuts
Evidently AIs like Claude expect unix languages to accept input on the commandline, e.g.

go run -e -c 'package main; func main() { println("hello"); }'

This mistake happens very frequently.  Presumably it's hallucinating -e and -c because various other tools accept those as flags to indicate the input is on the commandline.

I asked Claude's opinion on this:

--- snip ---

 Before you run that command, I'm going to file a bug against go to make your life easier.  Which example feels more natural to you for running short go programs: 1)  go run -c 'package main; func main()         

{println("hello");}'  or   2) echo 'package main; func main() {println("hello");}' | go run -         

------- snip ----

It replied:

------- snip ----                                                                                                               

Option 1 (go run -c '...') is what I instinctively reach for — it matches python -c, bash -c, perl -e. Less pipeline plumbing for quick checks.

------- snip ----

Why not obey the principle of least surprise here, and do what feels natural to this (non-sentient) user?

- Dan

Ian Lance Taylor

unread,
Jul 5, 2026, 9:36:23 PM (4 days ago) Jul 5
to Dan Kegel, golang-nuts
I don't feel strongly one way or another about whether the go tool
should support passing in the source, but I note that the suggested
approach would make "go run -c" very different from "go test -c".

Ian

Dan Kegel

unread,
Jul 5, 2026, 10:29:09 PM (4 days ago) Jul 5
to Ian Lance Taylor, golang-nuts
How about -e ?  That's what perl and ruby use.
- Dan

Jackie Li

unread,
Jul 6, 2026, 4:23:22 AM (4 days ago) Jul 6
to golang-nuts
I like this! currently quick testing locally have to start with a file. Also I think for AI agent to run quick script, this would be perfect

Rob Pike

unread,
Jul 6, 2026, 6:11:29 AM (4 days ago) Jul 6
to Jackie Li, golang-nuts
Surely these AI tools are powerful enough that you can tell them how to run the command rather than changing the language's tools to cover their inadequacies.

-rob


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/0d4be2ed-14a6-4a44-b834-704caede5ef0n%40googlegroups.com.

Dan Kegel

unread,
Jul 6, 2026, 10:33:24 PM (3 days ago) Jul 6
to Rob Pike, Jackie Li, golang-nuts
On Mon, Jul 6, 2026 at 3:10 AM Rob Pike <r...@golang.org> wrote:
Surely these AI tools are powerful enough that you can tell them how to run the command rather than changing the language's tools to cover their inadequacies.

I've observed people never bothering to do go build; they want to treat go like an interpreter.
And most popular interpreters offer a way to run code from the commandline.
Here's a little rosetta stone:

# Program coming from stdin

echo 'echo "Hello, World!"' | sh

echo 'echo "Hello, World!"' | pwsh

echo 'print("Hello, World!")' | python3

echo 'print "Hello, World!\n"' | perl

echo 'puts "Hello, World!"' | ruby

echo '<?php echo "Hello, World!\n"; ?>' | php

echo 'console.log("Hello, World!")' | node

echo 'print("Hello, World!")' | lua

#not supported in go


# Program coming from commandline option

sh -c 'echo "Hello, World!"'

pwsh -Command 'echo "Hello, World!"'

python3 -c 'print("Hello, World!")'

perl -e 'print "Hello, World!\n"'

ruby -e 'puts "Hello, World!"'

php -r 'echo "Hello, World!\n";'

node -e 'console.log("Hello, World!")'

lua -e 'print("Hello, World!")'

awk 'BEGIN{print "Hello, World!"}'

echo 'package main; func main() {println("Hello, world!")}' > hello.go; go run hello.go; rm hello.go


It does seem worth supporting, at least to me, as an idiom for quickly printing out constants or running really tiny programs.

- Dan

Sebastien Binet

unread,
Jul 7, 2026, 3:12:05 AM (3 days ago) Jul 7
to Dan Kegel, Rob Pike, Jackie Li, golang-nuts
another option is to contribute to mvm (even though, I personally won't
anymore as it does accept AI contributions):
https://github.com/mvm-sh/mvm

$> mvm run -e "fmt.Println(1+2)"
3

ie: if one wants interpreter-like features, better work with an
interpreter.

-s

PS: that said, I suppose one could perhaps consider 'go run' accepting
code from stdin.

Brian Candler

unread,
Jul 7, 2026, 4:01:13 AM (3 days ago) Jul 7
to golang-nuts
On Tuesday, 7 July 2026 at 03:33:24 UTC+1 Dan Kegel wrote:
Here's a little rosetta stone:
...

#not supported in go



To be fair, I'm not sure many other *compiled* languages do this either - perhaps the list should also include Rust, C, C++, Swift, Java ?

Stephen Illingworth

unread,
Jul 7, 2026, 4:37:32 AM (3 days ago) Jul 7
to golang-nuts
Just for fun, I wondered how easy it would be to create a bash script that facilitates using Go in this way.


Usage would be something like

   echo 'println("hello world"); fmt.Println("goodbye")' | GORUN

   echo 'println(math.Pi)' | GORUN

Or using actual newlines

   echo '
   println("hello world")
   println("goodbye")
   ' | GORUN


On Tuesday, 7 July 2026 at 03:33:24 UTC+1 Dan Kegel wrote:

Touring Tim

unread,
Jul 7, 2026, 4:47:20 AM (3 days ago) Jul 7
to Stephen Illingworth, golang-nuts
I've observed people never bothering to do go build.

I wonder who these people are and why they would be using GO in the first place?  Send to be a very complicated deployment to install GO on every deployment


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Dan Kegel

unread,
Jul 7, 2026, 12:19:16 PM (3 days ago) Jul 7
to golang-nuts
On Tuesday, July 7, 2026 at 1:47:20 AM UTC-7 Touring Tim wrote:
I've observed people never bothering to do go build.

I wonder who these people are and why they would be using GO in the first place?  Send to be a very complicated deployment to install GO on every deployment

Newly hired whippersnappers.  They see Go as just another language like Python, and since they're at a company that uses Go, that's what they use.
- Dan 

Raffaele Sena

unread,
Jul 7, 2026, 3:00:52 PM (3 days ago) Jul 7
to Dan Kegel, golang-nuts
I use Go since it came out, and I alternate. I have some applications
that I built and never change, and those are "built" and deployed (in
~/go/bin).
I have some applications that for one reason or another are always in
evolution (even if slow evolution) and I run them as "go run app.go".

Regarding the original subject, there are times where I just need to
quickly try out a standard library call, or do some string
manipulation, and I don't feel like writing a full program. For those
cases I use "gomacro" (because I remember that I have it installed).

In any case, since I started using Claude, I don't remember any case
where it tried to run "go run -c" vs. creating a file and running it.
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/4fedd0c9-bfd7-4da4-8f9e-3758bb5dfd6dn%40googlegroups.com.

Ian Lance Taylor

unread,
Jul 7, 2026, 3:08:53 PM (3 days ago) Jul 7
to Brian Candler, golang-nuts
On Tue, Jul 7, 2026 at 1:01 AM 'Brian Candler' via golang-nuts
<golan...@googlegroups.com> wrote:
>
> To be fair, I'm not sure many other *compiled* languages do this either - perhaps the list should also include Rust, C, C++, Swift, Java ?

One version for C (or C++) is a thing of beauty. It's a bit
inconvenient since you need to put the string in the middle of the
command. And you need to name an executable file. This assumes bash.

gcc -o /tmp/run -x c - <<< '#include <stdio.h>
int main() { printf("hello, world\n"); }' && /tmp/run

Ian

Dan Kegel

unread,
Jul 7, 2026, 3:30:36 PM (3 days ago) Jul 7
to golang-nuts
On Tuesday, July 7, 2026 at 12:08:53 PM UTC-7 Ian Lance Taylor wrote:
One version for C (or C++) is a thing of beauty. It's a bit
inconvenient since you need to put the string in the middle of the
command. And you need to name an executable file. This assumes bash.

gcc -o /tmp/run -x c - <<< '#include <stdio.h>
int main() { printf("hello, world\n"); }' && /tmp/run

Good point.   gcc comes close here!  

Go currently allows
echo 'package main; func main() {println("Hello, world!")}' > hello.go; go run hello.go; rm hello.go

but following gcc's example would let us shorten that to

echo 'package main; func main() {println("Hello, world!")}' | go run -

Jason E. Aten

unread,
Jul 7, 2026, 9:08:45 PM (3 days ago) Jul 7
to golang-nuts
Doesn't seem like it is worth the cost. 

This would need substantial added complexity in the standard toolchain, 
and the above shows there are easy workarounds to do party tricks.
 
So do the use cases described make it worth a very heavy cost? So far, no.

use cases described so far:

1. printing constants? "go doc" already does this. try:
go doc math.Pi

2. pandering to bad LLMs and window shoppers who don't know the language? 
both are bad ideas to begin with. Mr. Pike's objection is sustained.

3. printing "hello world" from Go on a single line?
not compelling.

I love me a REPL; I am a massive fan of R; and the party tricks are fun[1]; 
but you have failed to make any case that this heavy (high complexity cost) suggestion is worth it.

[1] kind of the same party trick as Ian's for C++ but in R, to make a script execute R (or any interpreter that can source a file from disk):

#!/bin/bash
exec R --vanilla -q --slave -e "source(file=pipe(\"tail -n +4 $0\"))" --args $@
#or debug version: exec R --vanilla --verbose -e "source(file=pipe(\"tail -n +4 $0\"))" --args $@
### The above line starts R and then reads in this script, starting at line 4:
# R code here... a simple linear regression for instance.
x = as.numeric(readLines("x.txt"))
y = as.numeric(readLines("y.txt"))
summary(lm(y ~ x))

Dan Kegel

unread,
Jul 7, 2026, 10:41:54 PM (2 days ago) Jul 7
to Jason E. Aten, golang-nuts
I figured Claude was an interested party, so I asked it to read this thread and comment.
Here's what it came back with:

  This proposal won't happen, and for good reasons:                                                                                                                   

                  

  1. The problem is backwards - LLMs hallucinating non-existent Go flags is a training data issue, not a Go toolchain issue. Fixing Go to match LLM hallucinations    

  sets a terrible precedent.

  2. The cost/benefit is poor - Adding inline code execution to go run is non-trivial (argument parsing, stdin handling, module context, error reporting) for marginal

   benefit. The pipe workaround works fine: echo 'package main; func main() { println("hi") }' | go run .                                                             

  3. Flag conflict - go test -c already means "compile but don't run." Overloading -c to mean "inline code" in go run violates consistency.

  4. Wrong tool for the job - If you want a Go REPL or quick evaluation, use dedicated tools like gomacro, gore, or yaegi. The go command is a build tool, not an     

  interpreter.                                                                                                                                                        

  5. The Pike objection - The reference to "Mr. Pike's objection" likely refers to Rob Pike's general philosophy against adding complexity for convenience when       

  simpler alternatives exist.                                                                                                                                         

                  

  The real fix: Update LLM training to stop hallucinating go run -c. This is a model correction issue, not a language tooling gap. 

Dan Kegel

unread,
Jul 7, 2026, 10:46:24 PM (2 days ago) Jul 7
to Jason E. Aten, golang-nuts
Note that Claude got the pipe workaround wrong :-)
Watch it stumble around looking for how to use the toolchain.  Poor thing.

❯ Are you sure that pipe workaround works?

⏺ Good catch. Let me test that:

⏺ Bash(echo 'package main; func main() { println("hi") }' | go run .)
  ⎿  Error: Exit code 1
     package github.com/signalsciences/sigsci-agent-core/smartparse is not a main package

⏺ Bash(cd /tmp && echo 'package main; func main() { println("hi") }' | go run .)
  ⎿  Error: Exit code 1
     go: go.mod file not found in current directory or any parent directory; see 'go help modules'

⏺ Bash(cd /tmp && echo 'package main
      func main() { println("hi") }' > test.go && go run test.go && rm test.go)
  ⎿  hi

⏺ Bash(cd /tmp && go run <(echo 'package main
      func main() { println("hi from process substitution") }'))
  ⎿  Error: Exit code 1
     go: go.mod file not found in current directory or any parent directory; see 'go help modules'

⏺ Bash(cd /tmp && GO111MODULE=off go run <(echo 'package main
      func main() { println("hi from process substitution") }'))
  ⎿  Error: Exit code 1
     import "/dev/fd/63": cannot import absolute path

⏺ Bash(cd /tmp && echo 'package main
      func main() { println("hi from stdin") }' | GO111MODULE=off go run /dev/stdin)
  ⎿  Error: Exit code 1
     import "/dev/stdin": cannot import absolute path

⏺ Bash(cd /tmp && cat > /tmp/inline.go << 'EOF' && GO111MODULE=off go run /tmp/inline.go && rm /tmp/inline.go
      package main…)
  ⎿  hi

⏺ You're absolutely right - I was wrong. That pipe doesn't work at all. Let me correct my analysis:

⏺ Bash(echo 'package main
      func main() { println("testing") }' | go run -)
  ⎿  Error: Exit code 1
     go: no go files listed

⏺ Corrected assessment:

  go run does not accept stdin at all. The only workaround is creating an actual temporary file:

  # This is the actual workaround - clunky and annoying:
  echo 'package main; func main() { println("hi") }' > /tmp/temp.go && go run /tmp/temp.go && rm /tmp/temp.go

  This actually strengthens the case for the proposal, not weakens it:

  1. Python/Perl/Ruby all support -c or -e for inline code - it's a legitimate use case
  2. The current Go workaround is genuinely bad - requiring temp file creation for a one-liner is clunky
  3. For quick experiments, having to create/delete temp files adds friction
  4. The LLM hallucination issue is real - it's not just bad training; it's LLMs correctly predicting what should exist based on Unix conventions

  However, the opposition's technical points still stand:
  - The -c flag conflict with go test -c is real
  - Adding stdin/inline support to go run isn't trivial
  - The complexity cost for the Go toolchain is real

  Better solution: Use existing tools like gomacro, gore, or yaegi for REPL-style experimentation. The go command being a build-focused tool (not an interpreter) is
  an intentional design choice.
Reply all
Reply to author
Forward
0 new messages