release.2009-12-22

41 views
Skip to first unread message

Russ Cox

unread,
Dec 22, 2009, 5:01:06 PM12/22/09
to golang-nuts
We've just tagged a new Go release, release.2009-12-22. As usual,
you can update by running:

hg pull
hg update release

Since the last release there has been one large syntactic change to
the language, already discussed extensively on this list: semicolons
are now implied between statement-ending tokens and newline characters.
See http://groups.google.com/group/golang-nuts/t/5ee32b588d10f2e9 for
details.

By default, gofmt now parses and prints the new lighter weight syntax.
To convert programs written in the old syntax, you can use:

gofmt -oldparser -w *.go

Since everything was being reformatted anyway, we took the opportunity to
change the way gofmt does alignment. Now gofmt uses tabs at the start
of a line for basic code alignment, but it uses spaces for alignment of
interior columns. Thus, in an editor with a fixed-width font, you can
choose your own tab size to change the indentation, and no matter what
tab size you choose, columns will be aligned properly.


In addition to the syntax and formatting changes, there have been many
smaller fixes and updates:

6g,8g,5g: many bug fixes, better registerization,
build process fix involving mkbuiltin (thanks Yongjian Xu),
method expressions for concrete types
8l: support for Windows PE files (thanks Hector Chu)
bytes: more efficient Buffer handling
bytes, strings: new function Fields (thanks Andrey Mirtchovski)
cgo: handling of enums (thanks Moriyoshi Koizumi),
handling of structs with bit fields, multiple files (thanks Devon
H. O'Dell),
installation of .so to non-standard locations
crypto/sha256: new package for SHA 256 (thanks Andy Davis)
encoding/binary: support for slices of fixed-size values (thanks Maxim Ushakov)
exp/vector: experimental alternate vector representation (thanks Jan Mercl)
fmt: %p for chan, map, slice types
gob: a couple more bug fixes
http: support for basic authentication (thanks Ivan Krasin)
image/jpeg: basic JPEG decoder
math: correct handling of Inf and NaN in Pow (thanks Charles Dorian)
misc/bash: completion file for bash (thanks Alex Ray)
os/signal: support for handling Unix signals (thanks David Symonds)
rand: Zipf-distributed random values (thanks William Josephson)
syscall: correct error return bug on 32-bit machines (thanks
Christopher Wedgwood)
syslog: new package for writing to Unix syslog daemon (thanks Yves Junqueira)
template: will automatically invoke niladic methods
time: new ISO8601 format generator (thanks Ben Olive)
xgb: converted generator to new syntax (thanks Tor Andersson)
xml: better mapping of tag names to Go identifiers (thanks Kei Son),
better handling of unexpected EOF (thanks Arvindh Rajesh Tamilmani)

My apologies if I have missed anyone's contributions in the above list.
We appreciate all the help.

To see all changes from the last release to this one, you can,
after updating, run

hg log -r release.2009-12-09:release.2009-12-22

Have fun!

Russ

Kevin Ballard

unread,
Dec 22, 2009, 5:04:30 PM12/22/09
to r...@golang.org, golang-nuts
On Tue, Dec 22, 2009 at 5:01 PM, Russ Cox <r...@golang.org> wrote:
Since everything was being reformatted anyway, we took the opportunity to
change the way gofmt does alignment.  Now gofmt uses tabs at the start
of a line for basic code alignment, but it uses spaces for alignment of
interior columns.  Thus, in an editor with a fixed-width font, you can
choose your own tab size to change the indentation, and no matter what
tab size you choose, columns will be aligned properly.

Thank you! I've always thought this was the only sensible way to handle tabs vs. spaces, and yet I've never encountered an editor that supports it. Glad to see Go supporting this!

-Kevin Ballard

--
Kevin Ballard
http://kevin.sb.org
kbal...@gmail.com

Pat Notz

unread,
Dec 22, 2009, 5:52:03 PM12/22/09
to Kevin Ballard, r...@golang.org, golang-nuts

Yeah, best new feature!

Marcin 'Qrczak' Kowalczyk

unread,
Dec 24, 2009, 2:45:15 PM12/24/09
to r...@golang.org, golang-nuts
2009/12/22 Russ Cox <r...@golang.org>:

> Since everything was being reformatted anyway, we took the opportunity to
> change the way gofmt does alignment.  Now gofmt uses tabs at the start
> of a line for basic code alignment, but it uses spaces for alignment of
> interior columns.  Thus, in an editor with a fixed-width font, you can
> choose your own tab size to change the indentation, and no matter what
> tab size you choose, columns will be aligned properly.

I consider a tab width different than 8 as evil because it's
impractical to configure every tool which displays code for a custom
tab width, and 8 is the most common default. Since an indent of 8
spaces is too big, it follows that code should not use tabs for
indentation. It's a pity that Go went this way.

--
Marcin Kowalczyk

atomly

unread,
Dec 24, 2009, 3:03:02 PM12/24/09
to Marcin 'Qrczak' Kowalczyk, r...@golang.org, golang-nuts
On Thu, Dec 24, 2009 at 2:45 PM, Marcin 'Qrczak' Kowalczyk <qrcz...@gmail.com> wrote:
I consider a tab width different than 8 as evil because it's
impractical to configure every tool which displays code for a custom
tab width, and 8 is the most common default. Since an indent of 8
spaces is too big, it follows that code should not use tabs for
indentation. It's a pity that Go went this way.

I think your first assumption is somewhat flimsy-- any decent editor that I've ever used has made it very easy to adjust the tab settings.

In addition, tabs are the _only_ flexible way to adjust the formatting of code without physically altering the code-- you can set your tabs to 4 spaces and I can set mine to 2, but as long as a tab's a tab, our source control will be happy... 


--
:: atomly ::

[ ato...@atomly.com : www.atomly.com  : http://blog.atomly.com/ ...
[ atomiq records : new york city : +1.917.442.9450 ...
[ e-mail atomly-new...@atomly.com for atomly info and updates ...

Marcin 'Qrczak' Kowalczyk

unread,
Dec 24, 2009, 3:56:37 PM12/24/09
to atomly, r...@golang.org, golang-nuts
2009/12/24 atomly <ato...@atomly.com>:

> I think your first assumption is somewhat flimsy-- any decent editor that
> I've ever used has made it very easy to adjust the tab settings.

<pre> in HTML?
paps (text to PostScript converter)?
Gnome Terminal?

> In addition, tabs are the _only_ flexible way to adjust the formatting of
> code without physically altering the code-- you can set your tabs to 4
> spaces and I can set mine to 2, but as long as a tab's a tab, our source
> control will be happy...

They are not flexible. For me a tab has the width of 8 spaces, and I
don't want to tweak the configuration of every tool used to display
code.

--
Marcin Kowalczyk

Ben Tilly

unread,
Dec 24, 2009, 4:57:52 PM12/24/09
to Marcin 'Qrczak' Kowalczyk, atomly, r...@golang.org, golang-nuts
On 12/24/09, Marcin 'Qrczak' Kowalczyk <qrcz...@gmail.com> wrote:
> 2009/12/24 atomly <ato...@atomly.com>:

> > In addition, tabs are the _only_ flexible way to adjust the formatting of
> > code without physically altering the code-- you can set your tabs to 4
> > spaces and I can set mine to 2, but as long as a tab's a tab, our source
> > control will be happy...
>
> They are not flexible. For me a tab has the width of 8 spaces, and I
> don't want to tweak the configuration of every tool used to display
> code.

And not just every tool, but every machine. I often find myself
logging in and reading code in a dozen different machines on several
operating systems. I therefore like leaving things at default
settings as much as possible.

That means that tabs have a width of 8 spaces for me.

Cheers,
Ben

Kevin Ballard

unread,
Dec 24, 2009, 5:00:22 PM12/24/09
to Ben Tilly, Marcin 'Qrczak' Kowalczyk, atomly, r...@golang.org, golang-nuts
Default on all GUI editors I've ever used on OS X has been 4-width tabs. So even when just sticking with the defaults, you can't assume 8-width tabs.

-Kevin Ballard

Jessta

unread,
Dec 24, 2009, 6:34:07 PM12/24/09
to golang-nuts
2009/12/23 Russ Cox <r...@golang.org>:

> Now gofmt uses tabs at the start
> of a line for basic code alignment, but it uses spaces for alignment of
> interior columns.  Thus, in an editor with a fixed-width font, you can
> choose your own tab size to change the indentation, and no matter what
> tab size you choose, columns will be aligned properly.

Woot!
I've been advocating this style for years and people tend to give me
funny looks and link me to this
http://www.emacswiki.org/pics/static/TabsSpacesBoth.png

- jessta
--
=====================
http://jessta.id.au

Tom Lieber

unread,
Dec 24, 2009, 7:40:30 PM12/24/09
to golang-nuts, Marcin 'Qrczak' Kowalczyk
On Thu, Dec 24, 2009 at 3:56 PM, Marcin 'Qrczak' Kowalczyk
<qrcz...@gmail.com> wrote:
>> In addition, tabs are the _only_ flexible way to adjust the formatting of
>> code without physically altering the code-- you can set your tabs to 4
>> spaces and I can set mine to 2, but as long as a tab's a tab, our source
>> control will be happy...
>
> They are not flexible. For me a tab has the width of 8 spaces, and I
> don't want to tweak the configuration of every tool used to display
> code.

Doesn't that make you the least flexible?

--
Tom Lieber
http://AllTom.com/

Anh Hai Trinh

unread,
Dec 27, 2009, 1:35:11 AM12/27/09
to Marcin 'Qrczak' Kowalczyk, atomly, golang-nuts
> For me a tab has the width of 8 spaces, and I
> don't want to tweak the configuration of every tool used to display
> code.

In comparison, N spaces always mean N spaces and nobody in the world
can make it look like N/2 spaces without actually changing the source
file. If a tab has to mean 8 spaces for you, I'm truly sorry! Blame
the defaults.

----aht

unread,
Dec 28, 2009, 7:45:16 AM12/28/09
to golang-nuts

To all: You are just some lunatics. There's no other rational
explanation.

The solution to the discussed problem is quite obvious. I do not
understand why are you even talking about this stuff. Why don't you
try to *identify* and *solve* the core of the problem!

And yes, I know what I am talking about. Because in the programming
language&environment I designed, this particular problem *is* solved.

Jessta

unread,
Dec 28, 2009, 7:55:05 AM12/28/09
to ⚛, golang-nuts
2009/12/28 ⚛ <0xe2.0x...@gmail.com>:

> The solution to the discussed problem is quite obvious. I do not
> understand why are you even talking about this stuff. Why don't you
> try to *identify* and *solve* the core of the problem!
The core problem is solved by gofmt and the fact that go doesn't give
semantic meaning to indentation so it's easy to just reformat to what
ever format you prefer and then convert bad.

> And yes, I know what I am talking about. Because in the programming
> language&environment I designed, this particular problem *is* solved.
>

which language and environment is that?

unread,
Dec 28, 2009, 9:41:23 AM12/28/09
to golang-nuts
On Dec 28, 1:55 pm, Jessta <jes...@gmail.com> wrote:
> 2009/12/28 ⚛ <0xe2.0x9a.0...@gmail.com>:> The solution to the discussed problem is quite obvious. I do not

> > understand why are you even talking about this stuff. Why don't you
> > try to *identify* and *solve* the core of the problem!
>
> The core problem is solved by gofmt and the fact that go doesn't give
> semantic meaning to indentation so it's easy to just reformat to what
> ever format you prefer and then convert bad.

I wasn't thinking about something different: The core problem is that
people on this forum thread expressed certain requirements/
expectations about code formatting - but failed to acknowledge that
the functionality they demand cannot be implemented by just
tabs&spaces. But instead of acknowledging this contradiction between
the requirements and the implementation mechanism, they just keep
going on debating tab&spaces. Therefore the debate seems irrational to
me. Existence of "gofmt" does not make a difference in this respect.

> > And yes, I know what I am talking about. Because in the programming
> > language&environment I designed, this particular problem *is* solved.
>
> which language and environment is that?

It's not public (if that's what you're asking).

befelemepeseveze

unread,
Dec 28, 2009, 10:01:45 AM12/28/09
to golang-nuts

If it's not *public* then it is quite unclear to me, what's the point
of a *public claim* it has any specific features/properties/solutions
at all?

unread,
Dec 28, 2009, 10:31:46 AM12/28/09
to golang-nuts
On Dec 28, 4:01 pm, befelemepeseveze <befelemepesev...@gmail.com>
wrote:

You have two options:

1. Simply ignore what I wrote. Continue debating all the tabs&spaces-
stuff without actually making advancements in the source-code-
formatting problem.

2. Or maybe: Give it a deeper though, because ⚛ claims that
tabs&spaces are by themselves insufficient to solve the problem and
claims that there *exists* a solution.

Make your pick.

(An analogy: The US made a *public* claim during the WWII that they
can make an A-bomb. It may seem unclear to some people, what's the
point of a *public claim* that the bomb had specific featured/
properties/solutions at all.)

Jessta

unread,
Dec 28, 2009, 10:43:08 AM12/28/09
to ⚛, golang-nuts
2009/12/29 ⚛ <0xe2.0x...@gmail.com>:

> 2. Or maybe: Give it a deeper though, because ⚛ claims that
> tabs&spaces are by themselves insufficient to solve the problem and
> claims that there *exists* a solution.
>
I've got a solution to world hunger and world peace and also a way of
travelling faster than light.
It's all in my secret lab.

Now you can keep debating whether it's possible to go faster than light,
or you can give it a deeper thought and try to solve the problem because
I'm claiming there exists a solution and trust me it's obviously
correct because I'm awesome!

...and that's all I have to say about that.
--
=====================
http://jessta.id.au

befelemepeseveze

unread,
Dec 28, 2009, 11:06:11 AM12/28/09
to golang-nuts
On 28 pro, 16:31, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> You have two options:
>
> 1. Simply ignore what I wrote. Continue debating all the tabs&spaces-
> stuff without actually making advancements in the source-code-
> formatting problem.
>
> 2. Or maybe: Give it a deeper though, because ⚛ claims that
> tabs&spaces are by themselves insufficient to solve the problem and
> claims that there *exists* a solution.
>
> Make your pick.

Actually my pick was to put a question: "...what's the point


of a *public claim* it has any specific features/properties/solutions

at all?". Unfortunately it hasn't got answered, so I can't learn any
new trick/solution to whatsoever - which was what I would like to do
and the reason to ask. But now I understand it - there's no chance
within that classified "eyes only" A-bomb related project. PS: It's
probably a security break to even talk about being involved, isn't
it? :)

unread,
Dec 28, 2009, 11:15:34 AM12/28/09
to golang-nuts
On Dec 28, 4:43 pm, Jessta <jes...@gmail.com> wrote:
> 2009/12/29 ⚛ <0xe2.0x9a.0...@gmail.com>:> 2. Or maybe: Give it a deeper though, because ⚛ claims that

> > tabs&spaces are by themselves insufficient to solve the problem and
> > claims that there *exists* a solution.
>
> I've got a solution to world hunger and world peace and also a way of
> travelling faster than light.
> It's all in my secret lab.
>
> Now you can keep debating whether it's possible to go faster than light,
> or you can give it a deeper thought and try to solve the problem because
>  I'm claiming there exists a solution and trust me it's obviously
> correct because I'm awesome!
>
> ...and that's all I have to say about that.

It is also these kinds of pointless reactions why I keep it private.

And, you didn't even bothered to refute my conjecture that tabs&spaces
are inherently insufficient. Good for you, at least you do not need to
suffer the consequences in case your thinking is wrong. I don't mind,
you can continue using the tabs&spaces-way of doing things until you
are 80 years old or something.

Tom Lieber

unread,
Dec 28, 2009, 11:21:36 AM12/28/09
to golang-nuts
This is surreal.

Helmar

unread,
Dec 28, 2009, 11:31:18 AM12/28/09
to golang-nuts
Hi,

see:

$ gofmt -help
usage: gofmt [flags] [path ...]
-tabwidth=8: tab width
-oldparser=false: parse old syntax (required semicolons)
-trace=false: print parse trace
-r="": rewrite rule (e.g., 'α[β:len(α)] -> α[β:]')
-tabindent=true: indent with tabs independent of -spaces
-oldprinter=false: print old syntax (required semicolons)
-l=false: list files whose formatting differs from gofmt's
-w=false: write result to (source) file instead of stdout
-spaces=true: align with spaces instead of tabs
-comments=true: print comments


there is nothing surreal there. They did not read the docs. Simply set
-tabindent=false and get spaces if you want them…
Hell is burning all time, but Heaven seems not to give light in these
times ;)

Regards,
-Helmar

unread,
Dec 28, 2009, 11:55:01 AM12/28/09
to golang-nuts
On Dec 25, 12:34 am, Jessta <jes...@gmail.com> wrote:
> 2009/12/23 Russ Cox <r...@golang.org>:
>
> > Now gofmt uses tabs at the start
> > of a line for basic code alignment, but it uses spaces for alignment of
> > interior columns.  Thus, in an editor with a fixed-width font, you can
> > choose your own tab size to change the indentation, and no matter what
> > tab size you choose, columns will be aligned properly.
>
> Woot!
> I've been advocating this style for years ...

http://golang.org/doc/go_spec.html#Function_literals
http://golang.org/doc/go_spec.html#Statements

In Go, function literals can be used within statements. I suppose
longer function literals should be formatted as multi-line blocks. So,
please tell me, how are you going to properly format such statements
in the style you are advocating. (And yes, my "secret
language&environment" can do it without breaking a sweat - though I am
of course *not* claiming there aren't other languages in which it is
also possible.)

Helmar

unread,
Dec 28, 2009, 12:05:27 PM12/28/09
to golang-nuts
Hehe, you've chosen the most unwanted and underrepresented feature of
Go.
Did you ever think of how to call an unnamed function? Impossible in
Go until you assign it to a variable. So the function literals are
only interesting as long as they do not use recursion (which should be
simpler in Go than in C...). Congrats, and hope the Go-designers think
a little bit better about this ;)

Regards,
-Helmar


On Dec 28, 11:55 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> On Dec 25, 12:34 am, Jessta <jes...@gmail.com> wrote:
>
> > 2009/12/23 Russ Cox <r...@golang.org>:
>
> > > Now gofmt uses tabs at the start
> > > of a line for basic code alignment, but it uses spaces for alignment of
> > > interior columns.  Thus, in an editor with a fixed-width font, you can
> > > choose your own tab size to change the indentation, and no matter what
> > > tab size you choose, columns will be aligned properly.
>
> > Woot!
> > I've been advocating this style for years ...
>

> http://golang.org/doc/go_spec.html#Function_literalshttp://golang.org/doc/go_spec.html#Statements

Ben Tilly

unread,
Dec 28, 2009, 12:22:56 PM12/28/09
to Helmar, golang-nuts
On Mon, Dec 28, 2009 at 9:05 AM, Helmar <hel...@gmail.com> wrote:
> Hehe, you've chosen the most unwanted and underrepresented feature of
> Go.
> Did you ever think of how to call an unnamed function? Impossible in
> Go until you assign it to a variable. So the function literals are
> only interesting as long as they do not use recursion (which should be
> simpler in Go than in C...). Congrats, and hope the Go-designers think
> a little bit better about this ;)

You can call an unnamed function immediately inline. Figuring out the
types to declare is a PITA, but if you want you can even write down
the Y-combinator to create a recursive anonymous function with no
explicit assignment.

Cheers,
Ben

baldmountain

unread,
Dec 28, 2009, 12:26:46 PM12/28/09
to golang-nuts
On Dec 28, 11:15 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> It is also these kinds of pointless reactions why I keep it private.

Well, you did make a strong statement with nothing to back it up.

Actually, I think a good number of folks are being run off. I keep
reading the digests, but have stopped any real involvement. I consider
myself to be reasonably experienced with different programming
languages as a developer, but I also realize I have zero language
design experience.

We are trying to help. Yes, we are making all the usual beginner
mistakes. But instead of pointing us to a proper place to learn about
this stuff, we get a slap on the wrist and are made to feel stupid.

I like being an early adopter. It's fun jumping in where others fear
to tread. But after a punch in the face or two, we'll go play
somewhere more fun...


geoff

Helmar

unread,
Dec 28, 2009, 12:32:39 PM12/28/09
to golang-nuts
Hi,

On Dec 28, 12:22 pm, Ben Tilly <bti...@gmail.com> wrote:
> On Mon, Dec 28, 2009 at 9:05 AM, Helmar <hel...@gmail.com> wrote:
> > Hehe, you've chosen the most unwanted and underrepresented feature of
> > Go.
> > Did you ever think of how to call an unnamed function? Impossible in
> > Go until you assign it to a variable. So the function literals are
> > only interesting as long as they do not use recursion (which should be
> > simpler in Go than in C...). Congrats, and hope the Go-designers think
> > a little bit better about this ;)
>
> You can call an unnamed function immediately inline.

How. There is no way except making this thing a variable you can call
(so no := or so).

>  Figuring out the
> types to declare is a PITA, but if you want you can even write down
> the Y-combinator to create a recursive anonymous function with no
> explicit assignment.

I'm not at the level of "Y-Combinator" - I simply want to call the
"body" of the function from itself. I do not see this from the
analytical point but from the very practical point to allow recursion
of a function. This is not as complicated as you think. Just think as
the machine would think like...

Regards,
-Helmar

Ben Tilly

unread,
Dec 28, 2009, 12:43:27 PM12/28/09
to Helmar, golang-nuts
On Mon, Dec 28, 2009 at 9:32 AM, Helmar <hel...@gmail.com> wrote:
> Hi,
>
> On Dec 28, 12:22 pm, Ben Tilly <bti...@gmail.com> wrote:
>> On Mon, Dec 28, 2009 at 9:05 AM, Helmar <hel...@gmail.com> wrote:
>> > Hehe, you've chosen the most unwanted and underrepresented feature of
>> > Go.
>> > Did you ever think of how to call an unnamed function? Impossible in
>> > Go until you assign it to a variable. So the function literals are
>> > only interesting as long as they do not use recursion (which should be
>> > simpler in Go than in C...). Congrats, and hope the Go-designers think
>> > a little bit better about this ;)
>>
>> You can call an unnamed function immediately inline.
>
> How. There is no way except making this thing a variable you can call
> (so no := or so).

Write the function definition down then put an opening parenthesis
after the closing brace.

>>  Figuring out the
>> types to declare is a PITA, but if you want you can even write down
>> the Y-combinator to create a recursive anonymous function with no
>> explicit assignment.
>
> I'm not at the level of "Y-Combinator" - I simply want to call the
> "body" of the function from itself. I do not see this from the
> analytical point but from the very practical point to allow recursion
> of a function. This is not as complicated as you think. Just think as
> the machine would think like...

Expressing recursion without assignment tends to be tricky in higher
level languages because there is no way to get at the currently
executing function definition. That is what the Y-combinator pattern
is *for*. (That said, in real code people just use assignment because
that is easier.) But here is a sample of an anonymous function being
declared and called inline. I've updated it slightly to remove
semicolons but haven't tested it so it might have minor syntax errors
(but probably doesn't).

package main

import "fmt"

type recurseInt func (recurseInt) (func (int) int)

func main () {
fmt.Printf(
"Y-combinator 5! is %d\n",
func (builder recurseInt) (func (int) int) {
return func (n int) int {
return builder(builder)(n)
}
}(
func (recurse recurseInt) (func (int) int) {
return func (n int) int {
if 0 == n {
return 1
}
return n * recurse(recurse)(n-1)
}
}
)(
5
)
)
}

Cheers,
Ben

unread,
Dec 28, 2009, 12:44:32 PM12/28/09
to golang-nuts
On Dec 28, 6:05 pm, Helmar <hel...@gmail.com> wrote:
> Hehe, you've chosen the most unwanted and underrepresented feature of
> Go.

I do not agree with that.

> Did you ever think of how to call an unnamed function?

Yes.

> Impossible in Go until you assign it to a variable.

Whoops, the second example at http://golang.org/doc/go_spec.html#Function_literals
calls an unnamed function *without* assigning it to a variable. Does
it mean your understanding of this is wrong? Well, of course not, how
could you be wrong, that's impossible.

> So the function literals are
> only interesting as long as they do not use recursion (which should be
> simpler in Go than in C...).

What are you saying? That it is categorically impossible to implement
a language in which it is possible to [recursively call an anonymous
function from within itself]?

As for Go, the fact that Go cannot *currently* do it is only a minor
problem. It can be fixed, if Go language designers choose so. I have
no doubts about that.

> Congrats, and hope the Go-designers think
> a little bit better about this ;)

I am sure you have a lot of "very useful" ideas to convey to them.

> Regards,
> -Helmar

befelemepeseveze

unread,
Dec 28, 2009, 12:49:58 PM12/28/09
to golang-nuts
On 28 pro, 18:32, Helmar <hel...@gmail.com> wrote:
> How. There is no way except making this thing a variable you can call
> (so no := or so).

package main

func main() { println(func() int { return 42 }()) }

Helmar

unread,
Dec 28, 2009, 12:57:07 PM12/28/09
to golang-nuts
Well,

On Dec 28, 12:44 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> On Dec 28, 6:05 pm, Helmar <hel...@gmail.com> wrote:
>
> > Hehe, you've chosen the most unwanted and underrepresented feature of
> > Go.
>
> I do not agree with that.

No? Think twice.

> > Did you ever think of how to call an unnamed function?
>
> Yes.

Maybe you did. Did you do in every possible condition?

> > Impossible in Go until you assign it to a variable.
>

> Whoops, the second example athttp://golang.org/doc/go_spec.html#Function_literals


> calls an unnamed function *without* assigning it to a variable.

Yes, but I do not need to express that this function does not call
itself. Maybe this is a concept you do not know about.

> Does
> it mean your understanding of this is wrong? Well, of course not, how
> could you be wrong, that's impossible.

You understanding of recursion is probably wrong. I do think you do
not have one.

> > So the function literals are
> > only interesting as long as they do not use recursion (which should be
> > simpler in Go than in C...).
>
> What are you saying? That it is categorically impossible to implement
> a language in which it is possible to [recursively call an anonymous
> function from within itself]?

Did I say something that causes you to mind that I mean that something
is categorically impossible because I did claim that Go is a language
that does the impossible? I said plainly that this is crap, because
this steals a good part of things that is possible with programming
languages - especially system programming languages.

> As for Go, the fact that Go cannot *currently* do it is only a minor
> problem. It can be fixed, if Go language designers choose so. I have
> no doubts about that.

That "minor" problem is a major one if you dig a little deeper.

> > Congrats, and hope the Go-designers think
> > a little bit better about this ;)
>
> I am sure you have a lot of "very useful" ideas to convey to them.

You do not have so?

-Helmar

unread,
Dec 28, 2009, 1:04:20 PM12/28/09
to golang-nuts

Hmm, my line of thinking is more imperative, I guess. I would make it
work by simply introducing a new keyword "this_func" or something
named like that. It seems like the most obvious solution to me:

func main () {
f := func (n int) int {


if 0 == n {return 1};

return n * this_func(n-1)
};

f(5);
}

unread,
Dec 28, 2009, 1:09:11 PM12/28/09
to golang-nuts
On Dec 28, 6:57 pm, Helmar <hel...@gmail.com> wrote:
> On Dec 28, 12:44 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> > Yes.
>
> Maybe you did. Did you do in every possible condition?

What "every possible condition" in particular do you have in mind?

> > > Impossible in Go until you assign it to a variable.
>
> > Whoops, the second example athttp://golang.org/doc/go_spec.html#Function_literals
> > calls an unnamed function *without* assigning it to a variable.
>
> Yes, but I do not need to express that this function does not call
> itself. Maybe this is a concept you do not know about.

Just show me an example of a function you have on your mind.

Ian Lance Taylor

unread,
Dec 28, 2009, 1:10:37 PM12/28/09
to Helmar, golang-nuts
Helmar <hel...@gmail.com> writes:

> Did you ever think of how to call an unnamed function? Impossible in
> Go until you assign it to a variable. So the function literals are
> only interesting as long as they do not use recursion (which should be
> simpler in Go than in C...). Congrats, and hope the Go-designers think
> a little bit better about this ;)

Function literals can call themselves recursively, it's just awkward.

package main
import "fmt"
func main() {
var f func(int) int
f = func(i int) int {
if i == 0 {
return 1
}
return i * f(i - 1)
}
fmt.Println(f(5))
}

We could make it easier for function literals to call themselves
recursively, but it's hard to see how to make it easier to write
mutually recursive function literals.

Ian

Ben Tilly

unread,
Dec 28, 2009, 1:19:43 PM12/28/09
to Ian Lance Taylor, Helmar, golang-nuts

I think that is what Helmar means by "assigning it to a variable".

I'm not sure why he insisted on that artificial requirement, but I
agree that in practice assignment is a perfectly good solution.

Cheers,
Ben

Helmar

unread,
Dec 28, 2009, 1:27:40 PM12/28/09
to golang-nuts
Hi,

you still need to assign this function literal to a variable to call
it recursively. Well, for now this is a good workaround. Better would
be to have a recurse(...)-keyword to call the unnamed/local function.
It would make it more suitable for the fact that these function
literals are allowed everywhere where it is suitable. In case I want
to pass a recursive function to another function - at the moment I
would have to waste a variable(-name) (and pre-declare it) in every
case to get success. This is useless complexity. As language designers
you should not too much depend on "Google-deathmatch"-things, where
always the answer is "yes, but nobody uses it". Nobody can use it in
case of Go. Here are not only people that played with self-designed
languages. Here are people that implemented other languages and even
people that do have no experience with different languages at all (as
I see some here with loud voices). Back to recursion: this is a basic
thing, especially in local funcs, since there I can use the outer
named func for embedding and shielding the part that is recursive. As
of now, this is not very well implemented. I hope for later releases
to address the related issues.

Regards and thanks for good work,
-Helmar

unread,
Dec 28, 2009, 2:33:36 PM12/28/09
to golang-nuts

Well, I have beaten you by 23 minutes on this one.

> It would make it more suitable for the fact that these function
> literals are allowed everywhere where it is suitable. In case I want
> to pass a recursive function to another function

Why did you write you want to pass *recursive* function to another
function? Wouldn't it be sufficient to write that you want to pass a
function to another function? (Notice the absence of the word
"recursive" in the second question.) Is "recursive function" different
from "non-recursive function" from an implementation point of view?
Moreover, a function in general does not know at compile-time whether
it is recursive or not, because it can receive a reference to itself
at run-time.

> - at the moment I
> would have to waste a variable(-name) (and pre-declare it) in every
> case to get success. This is useless complexity. As language designers
> you should not too much depend on "Google-deathmatch"-things, where
> always the answer is "yes, but nobody uses it". Nobody can use it in
> case of Go.

You are not making any sense.

> Here are not only people that played with self-designed
> languages. Here are people that implemented other languages and even
> people that do have no experience with different languages at all (as
> I see some here with loud voices).

I wish you expressed your ideas more clearly, because I am not sure
what you mean by this. And I would like to know what do you mean by
this, but cannot decode the meaning of it from the incoherent
sentences you wrote.

> [cut]

Helmar

unread,
Dec 28, 2009, 2:54:12 PM12/28/09
to golang-nuts
Hi,

Ah, ok, we where in supermarket to buy something and things like this.
I do not want to beat anyone who thinks carefully about something in
terms of "time". This would be too - well - I think too short
thinking.

> > It would make it more suitable for the fact that these function
> > literals are allowed everywhere where it is suitable. In case I want
> > to pass a recursive function to another function
>
> Why did you write you want to pass *recursive* function to another
> function? Wouldn't it be sufficient to write that you want to pass a
> function to another function? (Notice the absence of the word
> "recursive" in the second question.)

You miss the point of the things. It's impossible to even define a
local func that is recursive without the variable. I can not pass a
local/noname func to another func where the passed func is standalone
(without variable) and uses recursion by itself. You simply can not
call that function since you have no other hook than assigning it
first to a variable-like thing.

> Is "recursive function" different
> from "non-recursive function" from an implementation point of view?

Yes. Definitely. With a recursive function you need to be able to call
the body of the function that is currently in definition process. This
is fundamental different. Usually functions you want to call are
defined already (and be it in C by the header file).

> Moreover, a function in general does not know at compile-time whether
> it is recursive or not, because it can receive a reference to itself
> at run-time.

Bullshit. You are too far from practice. Of course you can construct
recursion by passing function pointers. No doubts… But you can
optimize functions where you know they are recursive ;) And if you
want to bring fundamental logic here: It's not clear in general if not
a function is recursive. But you can determine if a function is
determinated to be recursive and if a function can in no case be
recursive. These cases are the most common. Where you do not know it
exactly is where a function gets a pointer to a function and this
function pointer is used to call the passed function. In usual
programs such a case is uncommon.

> > - at the moment I
> > would have to waste a variable(-name) (and pre-declare it) in every
> > case to get success. This is useless complexity. As language designers
> > you should not too much depend on "Google-deathmatch"-things, where
> > always the answer is "yes, but nobody uses it". Nobody can use it in
> > case of Go.
>
> You are not making any sense.

You do require that I'm a sense-making machine? Or do you simply not
understand what I mean? You could ask me what I mean. That would be
more nice than lifting me to the level of a machine that makes sense
or makes no sense.

> > Here are not only people that played with self-designed
> > languages. Here are people that implemented other languages and even
> > people that do have no experience with different languages at all (as
> > I see some here with loud voices).
>
> I wish you expressed your ideas more clearly, because I am not sure
> what you mean by this. And I would like to know what do you mean by
> this, but cannot decode the meaning of it from the incoherent
> sentences you wrote.

Mhm, please express more clearly what you did not understand. This
would help to formulate a more clear message that fits your mind.

Regards,
-Helmar

Ian Lance Taylor

unread,
Dec 28, 2009, 2:58:50 PM12/28/09
to baldmountain, golang-nuts
baldmountain <baldmo...@gmail.com> writes:

> Actually, I think a good number of folks are being run off. I keep
> reading the digests, but have stopped any real involvement. I consider
> myself to be reasonably experienced with different programming
> languages as a developer, but I also realize I have zero language
> design experience.
>
> We are trying to help. Yes, we are making all the usual beginner
> mistakes. But instead of pointing us to a proper place to learn about
> this stuff, we get a slap on the wrist and are made to feel stupid.
>
> I like being an early adopter. It's fun jumping in where others fear
> to tread. But after a punch in the face or two, we'll go play
> somewhere more fun...

It's certainly not the intent of anybody on the Go team to slap people
on the wrist, much less punch them in the face. I'm sorry if it seems
that way.

I would also love to know a proper place to learn about this stuff.
Mostly I think you have to learn by doing.

Ian

Ian Lance Taylor

unread,
Dec 28, 2009, 3:05:10 PM12/28/09
to Helmar, golang-nuts
Helmar <hel...@gmail.com> writes:

> On Dec 28, 1:10 pm, Ian Lance Taylor <i...@google.com> wrote:
>> Helmar <hel...@gmail.com> writes:
>> > Did you ever think of how to call an unnamed function? Impossible in
>> > Go until you assign it to a variable. So the function literals are
>> > only interesting as long as they do not use recursion (which should be
>> > simpler in Go than in C...). Congrats, and hope the Go-designers think
>> > a little bit better about this ;)
>>
>> Function literals can call themselves recursively, it's just awkward.
>>
>> package main
>> import "fmt"
>> func main() {
>>         var f func(int) int
>>         f = func(i int) int {
>>                 if i == 0 {
>>                         return 1
>>                 }
>>                 return i * f(i - 1)
>>         }
>>         fmt.Println(f(5))
>>
>> }
>>
>> We could make it easier for function literals to call themselves
>> recursively, but it's hard to see how to make it easier to write
>> mutually recursive function literals.
>
> you still need to assign this function literal to a variable to call
> it recursively.

Yes, sorry, I didn't really read your message properly.


> Well, for now this is a good workaround. Better would
> be to have a recurse(...)-keyword to call the unnamed/local function.

We've considered things along those lines, but they don't solve the
problem of mutually recursive function literals. I think a new
keyword would be a heavy cost to pay purely to permit function
literals to call themselves, particularly when there is already a
reasonably simple way to do it.

How do other languages address this?

Ian

befelemepeseveze

unread,
Dec 28, 2009, 3:27:54 PM12/28/09
to golang-nuts
On 28 pro, 20:54, Helmar <hel...@gmail.com> wrote:
> You miss the point of the things. It's impossible to even define a
> local func that is recursive without the variable.

Maybe you have missed Ben Tilly's post, which does the
"impossible" (here updated a little bit to compile with f3b247dddd57
tip)

package main

import "fmt"

type recurseInt func(recurseInt) (func(int) int)

func main() {
fmt.Printf(
"Y-combinator 5! is %d\n",
func(builder recurseInt) (func(int) int) {
return func(n int) int { return builder(builder)(n) }
}(func(recurse recurseInt) (func(int) int) {

return func(n int) int {


if 0 == n {
return 1
}
return n * recurse(recurse)(n-1)
}
})(5))
}

Still I would go for a variable as shown by Ian Lance Taylor as it is
much easier, but if you insist on not having the var, you can do it.

Helmar

unread,
Dec 28, 2009, 3:42:47 PM12/28/09
to golang-nuts
Hi,

On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:

> Yes, sorry, I didn't really read your message properly.

OK, no problem.

> > Well, for now this is a good workaround. Better would
> > be to have a recurse(...)-keyword to call the unnamed/local function.
>
> We've considered things along those lines, but they don't solve the
> problem of mutually recursive function literals.

Maybe I did not understand "mutually recursive". Could you explain it,
if that is something special? As I understand it now, Go would not
loose anything if it would allow recursion to nonames by a special
construct (keyword) of the language. It would make it for the usual
case much more simpler to get recursion - eg. you could use it with a
literal at every place and without an extra defined variable.

>  I think a new
> keyword would be a heavy cost to pay purely to permit function
> literals to call themselves, particularly when there is already a
> reasonably simple way to do it.

Mhm, I think this way is not really simple. You can not quickly try a
recursive thing that is nameless passed to a function. Even with named
functions I would like to have a way to access recursion without
memorizing how the function is called I working on ;) (well, this is
very constructed - I would know it in every case - but not having
named references to what I define at the moment could be useful).

> How do other languages address this?

What I most know about is Forth: they have a word called "RECURSE"
there, that works for named things and nonames as making the call to
the current definition. This is very clean and simple to understand. I
do not know of cases where someone wants to have access to a lower
level of definition (eg. when local functions are nested and someone
wants to access the outer one). The more and most common case should
be that the function that is in definition needs to be called. Since
this function has it's definition it should not be much work - well,
it is a keyword more but this single keyword would make recursion more
seamless and better integrated into language.

Regards,
-Helmar

Ben Tilly

unread,
Dec 28, 2009, 4:11:54 PM12/28/09
to Helmar, golang-nuts
On 12/28/09, Helmar <hel...@gmail.com> wrote:
> On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:
>
> > > Well, for now this is a good workaround. Better would
> > > be to have a recurse(...)-keyword to call the unnamed/local function.
> >
> > We've considered things along those lines, but they don't solve the
> > problem of mutually recursive function literals.
>
> Maybe I did not understand "mutually recursive". Could you explain it,
> if that is something special?

Mutually recursive functions are a set of functions that call each
other recursively.

> As I understand it now, Go would not
> loose anything if it would allow recursion to nonames by a special
> construct (keyword) of the language. It would make it for the usual
> case much more simpler to get recursion - eg. you could use it with a
> literal at every place and without an extra defined variable.

It would make the language bigger for no real improvement.

[...]


> > How do other languages address this?
>
> What I most know about is Forth: they have a word called "RECURSE"
> there, that works for named things and nonames as making the call to
> the current definition. This is very clean and simple to understand. I
> do not know of cases where someone wants to have access to a lower
> level of definition (eg. when local functions are nested and someone
> wants to access the outer one). The more and most common case should
> be that the function that is in definition needs to be called. Since
> this function has it's definition it should not be much work - well,
> it is a keyword more but this single keyword would make recursion more
> seamless and better integrated into language.

That makes Forth unusual then. AFAIK most other languages don't have
any special support for this. To the best of my knowledge that
includes the major scripting languages (Perl, Python and Ruby) and
Lisp variants (Scheme, Common Lisp).

Interestingly the other well-known language that I believe supports
this feature is Smalltalk through thisContext. You can get at your
whole stack that way, and can find out each function call. While
being able to get at stack frames as objects is is a cool feature,
adding support for it to Go would add overhead to every call, and I
don't think that overhead fits with Go's design features. Furthermore
I wouldn't want to read and modify code that got at the mutually
recurring function as being X calls back on the stack. I'd far prefer
to work with code that stuck the other function in a variable in an
enclosing environment and then called it by name.

Cheers,
Ben

Helmar

unread,
Dec 28, 2009, 4:27:06 PM12/28/09
to golang-nuts
Hi,

On Dec 28, 4:11 pm, Ben Tilly <bti...@gmail.com> wrote:
> On 12/28/09, Helmar <hel...@gmail.com> wrote:
>
> >  On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:
>
> >  > > Well, for now this is a good workaround. Better would
> >  > > be to have a recurse(...)-keyword to call the unnamed/local function.
>
> >  > We've considered things along those lines, but they don't solve the
> >  > problem of mutually recursive function literals.
>
> > Maybe I did not understand "mutually recursive". Could you explain it,
> >  if that is something special?
>
> Mutually recursive functions are a set of functions that call each
> other recursively.

OK, nothing I'm interested to address directly.

> > As I understand it now, Go would not
> >  loose anything if it would allow recursion to nonames by a special
> >  construct (keyword) of the language. It would make it for the usual
> >  case much more simpler to get recursion - eg. you could use it with a
> >  literal at every place and without an extra defined variable.
>
> It would make the language bigger for no real improvement.

Sure? Go function literals are crippled if you take a look at them
from the recursion point of view.

The real improvement "recursion" can not be, since there are not much
people out there that can make good use of it. It's indeed much too
complicated for many people.

> [...]
>
> >  > How do other languages address this?
>
> > What I most know about is Forth: they have a word called "RECURSE"
> >  there, that works for named things and nonames as making the call to
> >  the current definition. This is very clean and simple to understand. I
> >  do not know of cases where someone wants to have access to a lower
> >  level of definition (eg. when local functions are nested and someone
> >  wants to access the outer one). The more and most common case should
> >  be that the function that is in definition needs to be called. Since
> >  this function has it's definition it should not be much work - well,
> >  it is a keyword more but this single keyword would make recursion more
> >  seamless and better integrated into language.
>
> That makes Forth unusual then.  AFAIK most other languages don't have
> any special support for this.  To the best of my knowledge that
> includes the major scripting languages (Perl, Python and Ruby) and
> Lisp variants (Scheme, Common Lisp).

Mhm. Assembler can do it too (of course). Someone told that Javascript
can do it. Perl can do it too (you've to re-read docs ;) - it's not
simple to make but it can be done).

> Interestingly the other well-known language that I believe supports
> this feature is Smalltalk through thisContext.  You can get at your
> whole stack that way, and can find out each function call.

Why you need the complete stack? That is completely misleading and
uninteresting for recursion. The function simply needs the ability to
call itself. In C you do this by declaring the function in an include-
file. This is nothing new. C has no nonames and as such not the
problem to make them recursive...

>  While
> being able to get at stack frames as objects is is a cool feature,
> adding support for it to Go would add overhead to every call,

Tell my why

ab:
...
CALL ab
...
return

"CALL ab" introduces extra overhead. There is no overhead. This is
nonsense.

> and I
> don't think that overhead fits with Go's design features.  Furthermore
> I wouldn't want to read and modify code that got at the mutually
> recurring function as being X calls back on the stack.  I'd far prefer
> to work with code that stuck the other function in a variable in an
> enclosing environment and then called it by name.

You can still do that. If you do not want to deal with some code, let
other people do it.

Regards,
-Helmar

unread,
Dec 28, 2009, 4:34:56 PM12/28/09
to golang-nuts

On Dec 28, 8:54 pm, Helmar <hel...@gmail.com> wrote:
> Hi,
>

> On Dec 28, 2:33 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > Well, I have beaten you by 23 minutes on this one.
>
> Ah, ok, we where in supermarket to buy something and things like this.
> I do not want to beat anyone who thinks carefully about something in
> terms of "time". This would be too - well - I think too short
> thinking.

I think your analogy is in appropriate. The thing is, in a free market
economy, it does not matter whether a person arrives at a supermarket
at time T or T+20. The goods, food, etc will always be there waiting
for you, since there is a slight oversupply. In a communist economy,
or some rural environment without any supermarkets, this may not be
the case. But if you are living in a city, this *is* mostly the case.

> > > It would make it more suitable for the fact that these function
> > > literals are allowed everywhere where it is suitable. In case I want
> > > to pass a recursive function to another function
>
> > Why did you write you want to pass *recursive* function to another
> > function? Wouldn't it be sufficient to write that you want to pass a
> > function to another function? (Notice the absence of the word
> > "recursive" in the second question.)
>
> You miss the point of the things. It's impossible to even define a
> local func that is recursive without the variable.

I am not talking about whether it is right now possible in Go. I am
talking about whether it is possible in general.

> I can not pass a
> local/noname func to another func where the passed func is standalone
> (without variable) and uses recursion by itself. You simply can not
> call that function since you have no other hook than assigning it
> first to a variable-like thing.
>
> > Is "recursive function" different
> > from "non-recursive function" from an implementation point of view?
>
> Yes. Definitely. With a recursive function you need to be able to call
> the body of the function that is currently in definition process. This
> is fundamental different.

No it is not. The underlying structure formed by functions is a graph.
I can agree that non-recursive functions form tree-like structures -
but that does *not* matter if you are a language designer. As a
language designer you are solving the general case - and the general
case is that functions mimic graphs. The fact that some graphs are
trees is completely pointless in this case.

> Usually functions you want to call are
> defined already (and be it in C by the header file).

C header files contain *declarations* of functions, not their
*definitions*.

> > Moreover, a function in general does not know at compile-time whether
> > it is recursive or not, because it can receive a reference to itself
> > at run-time.
>
> Bullshit. You are too far from practice.

Oh really? But what about virtual methods in C++, or methods in Java
which require dynamic binding? Are you implying that it is uncommon
for a C++ virtual method to "call itself" (albeit in the context of a
different instance of the C++ class in question). What languages do
you know besides Forth?

> Of course you can construct
> recursion by passing function pointers. No doubts… But you can
> optimize functions where you know they are recursive ;)

You mean tail recursion? If you do, then why didn't you simply wrote
that you are talking about tail recursion?

> And if you
> want to bring fundamental logic here: It's not clear in general if not
> a function is recursive. But you can determine if a function is
> determinated to be recursive and if a function can in no case be
> recursive. These cases are the most common.

You are clearly forgetting about dynamic binding, which mostly uses
pointers to functions (C++, Java, Smalltalk, etc). The Linux kernel
(implemented in C) also makes a good use of function pointers (in the
filesystem, in interfaces to modules).

> Where you do not know it
> exactly is where a function gets a pointer to a function and this
> function pointer is used to call the passed function. In usual
> programs such a case is uncommon.

I think you are wrong.

> > > - at the moment I
> > > would have to waste a variable(-name) (and pre-declare it) in every
> > > case to get success. This is useless complexity. As language designers
> > > you should not too much depend on "Google-deathmatch"-things, where
> > > always the answer is "yes, but nobody uses it". Nobody can use it in
> > > case of Go.
>
> > You are not making any sense.
>
> You do require that I'm a sense-making machine? Or do you simply not
> understand what I mean? You could ask me what I mean. That would be
> more nice than lifting me to the level of a machine that makes sense
> or makes no sense.

I have no idea what "Google-deatchmacth" means.

> > > Here are not only people that played with self-designed
> > > languages. Here are people that implemented other languages and even
> > > people that do have no experience with different languages at all (as
> > > I see some here with loud voices).
>
> > I wish you expressed your ideas more clearly, because I am not sure
> > what you mean by this. And I would like to know what do you mean by
> > this, but cannot decode the meaning of it from the incoherent
> > sentences you wrote.
>
> Mhm, please express more clearly what you did not understand. This
> would help to formulate a more clear message that fits your mind.

I do not understand the whole paragraph.

> Regards,

Whatever.

> -Helmar

Ben Tilly

unread,
Dec 28, 2009, 5:08:36 PM12/28/09
to Helmar, golang-nuts
On 12/28/09, Helmar <hel...@gmail.com> wrote:
> On Dec 28, 4:11 pm, Ben Tilly <bti...@gmail.com> wrote:
> > On 12/28/09, Helmar <hel...@gmail.com> wrote:
> > > On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:
[...]

> > > As I understand it now, Go would not
> > > loose anything if it would allow recursion to nonames by a special
> > > construct (keyword) of the language. It would make it for the usual
> > > case much more simpler to get recursion - eg. you could use it with a
> > > literal at every place and without an extra defined variable.
> >
> > It would make the language bigger for no real improvement.
>
> Sure? Go function literals are crippled if you take a look at them
> from the recursion point of view.

Crippled? Adding one assignment statement is not a big change.

> The real improvement "recursion" can not be, since there are not much
> people out there that can make good use of it. It's indeed much too
> complicated for many people.

I firmly believe that anyone who is capable of actually understanding
recursion can figure out the assignment version. (The Y-combinator
version is harder but unnecessary since it isn't buying anything in
this case other than some abstract notion of "purity".)

[...]


> > That makes Forth unusual then. AFAIK most other languages don't have
> > any special support for this. To the best of my knowledge that
> > includes the major scripting languages (Perl, Python and Ruby) and
> > Lisp variants (Scheme, Common Lisp).
>
> Mhm. Assembler can do it too (of course). Someone told that Javascript
> can do it. Perl can do it too (you've to re-read docs ;) - it's not
> simple to make but it can be done).

Assembler is obvious.

I know how JavaScript used to be able to do it. However the rich
version of caller() that let it happen has been removed from recent
browsers because it was a source of too many security holes. The more
restricted arguments.caller property can't let you get at the
currently executing subroutine. I am not a JavaScript programmer so
it may still be possible, but if so then I don't know how.

I'm not sure what method you are thinking of for Perl. I'm going to
guess you are thinking of the fact that the current subroutine is in
(caller(0))[3] which you can use to dynamically find the function in
the symbol table. However that is a *string* representing the current
subroutine. If the current subroutine is a closure in someone else's
scope, you aren't going to get at that closure. You could, of course,
call some XS code that can get at the current subroutine, but I think
we can both agree that at that point you aren't really working within
the language.

> > Interestingly the other well-known language that I believe supports
> > this feature is Smalltalk through thisContext. You can get at your
> > whole stack that way, and can find out each function call.
>
> Why you need the complete stack?

You don't need it. It just happens that the same mechanism which can
give you access to the current calling function actually gives you
access to the whole call stack, which you can then do fun things with
like wrap it in a continuation. See the Seaside framework for some
interesting uses of this facility.

> That is completely misleading and
> uninteresting for recursion. The function simply needs the ability to
> call itself. In C you do this by declaring the function in an include-
> file. This is nothing new. C has no nonames and as such not the
> problem to make them recursive...

This comment really makes me wonder what it is you think is difficult.
In Go you can just call the current named function. Or you can call
the current anonymous function if it is in a variable in scope.
Between those two mechanisms you can do anything that I can think of
that you'd want to do.

Perhaps you are concerned that sticking the current function in a
variable in scope risks having a different variable put there at some
point? With closures and tightly scoped function declarations that is
a non-issue..

> > While
> > being able to get at stack frames as objects is is a cool feature,
> > adding support for it to Go would add overhead to every call,
>
> Tell my why

At run time you'd have to be able to find the type signature of the
executing function and then validate that you can call it. I don't
know whether those type signatures are kept at runtime on the current
stack, but I see no reason why they would be and therefore suspect
that they aren't.

> ab:
> ...
> CALL ab
> ...
> return
>
> "CALL ab" introduces extra overhead. There is no overhead. This is
> nonsense.

I'm sure you think you are making some brilliant and subtle point, but
what you said really doesn't make sense to me. Sorry.

> > and I
> > don't think that overhead fits with Go's design features. Furthermore
> > I wouldn't want to read and modify code that got at the mutually
> > recurring function as being X calls back on the stack. I'd far prefer
> > to work with code that stuck the other function in a variable in an
> > enclosing environment and then called it by name.
>
> You can still do that. If you do not want to deal with some code, let
> other people do it.

My preference is not because I have an odd aesthetic. My preference
is because I believe that one style is much more problematic and
likely to have bugs than the other.

I don't think that Go should deliberately add features to support bad
coding practices.

Cheers,
Ben

Ian Lance Taylor

unread,
Dec 28, 2009, 5:12:03 PM12/28/09
to Helmar, golang-nuts
Helmar <hel...@gmail.com> writes:

> On Dec 28, 4:11 pm, Ben Tilly <bti...@gmail.com> wrote:
>> On 12/28/09, Helmar <hel...@gmail.com> wrote:
>>
>> >  On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:
>>
>> >  > We've considered things along those lines, but they don't solve the
>> >  > problem of mutually recursive function literals.
>>
>> > Maybe I did not understand "mutually recursive". Could you explain it,
>> >  if that is something special?
>>
>> Mutually recursive functions are a set of functions that call each
>> other recursively.
>
> OK, nothing I'm interested to address directly.

But mutually recursive functions are a simple and natural
generalization of singly recursive functions. If we add a special
case to address the latter, why shouldn't we add a special case to
address the former? And if we add a special case for the former, it
should naturally address the latter case.


>> >  > How do other languages address this?
>>
>> > What I most know about is Forth: they have a word called "RECURSE"
>> >  there, that works for named things and nonames as making the call to
>> >  the current definition.

I think Forth is kind of a special case, though. In Forth a function
has no name until it is defined, so a RECURSE call is quite useful to
refer to the function being defined. And in Forth it's comparatively
difficult to write mutually recursive functions. In Go ordinary
functions can of course be both recursive and mutually recursive. We
are only talking about function literals here, and Go does make it
reasonably easy to give function literals a name by using a variable.
So I don't think the special case of Forth is a very good guide for
Go.


> Mhm. Assembler can do it too (of course). Someone told that Javascript
> can do it. Perl can do it too (you've to re-read docs ;) - it's not
> simple to make but it can be done).

You can't write a recursive call to an anonymous function in
assembler, except via constructs that are very difficult to use
correctly like "call . - 20".

In Javascript, you can't call an anonymous function recursively, but
you can give a function literal a name. That is, you can write:

var f = function fact(x) { if (x<=1) return 1; else return x*fact(x-1); }

That would be an approach we could use in Go but it also does not
address the problem of mutually recursive functions.

That said, Javascript also supports "arguments.callee". That is cheap
in an interpreted language but not something we are likely to support
in GO. In Perl6 you can refer to the &?BLOCK variable, which is
similar.

Ian

Helmar

unread,
Dec 28, 2009, 5:14:20 PM12/28/09
to golang-nuts

On Dec 28, 4:34 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> On Dec 28, 8:54 pm, Helmar <hel...@gmail.com> wrote:
>
> > Hi,
>
> > On Dec 28, 2:33 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > > Well, I have beaten you by 23 minutes on this one.
>
> > Ah, ok, we where in supermarket to buy something and things like this.
> > I do not want to beat anyone who thinks carefully about something in
> > terms of "time". This would be too - well - I think too short
> > thinking.
>
> I think your analogy is in appropriate. The thing is, in a free market
> economy, it does not matter whether a person arrives at a supermarket
> at time T or T+20. The goods, food, etc will always be there waiting
> for you, since there is a slight oversupply. In a communist economy,
> or some rural environment without any supermarkets, this may not be
> the case. But if you are living in a city, this *is* mostly the case.

Do I have more time in communism?

> > > > It would make it more suitable for the fact that these function
> > > > literals are allowed everywhere where it is suitable. In case I want
> > > > to pass a recursive function to another function
>
> > > Why did you write you want to pass *recursive* function to another
> > > function? Wouldn't it be sufficient to write that you want to pass a
> > > function to another function? (Notice the absence of the word
> > > "recursive" in the second question.)
>
> > You miss the point of the things. It's impossible to even define a
> > local func that is recursive without the variable.
>
> I am not talking about whether it is right now possible in Go. I am
> talking about whether it is possible in general.

Ah, but you mention communism - I've to say that I'm the expert in
communism here. I lived in such a system that wanted to reach
communism. I had not much more time there than today (well, we had
mechanic clocks and sometimes they stopped...)

> > I can not pass a
> > local/noname func to another func where the passed func is standalone
> > (without variable) and uses recursion by itself. You simply can not
> > call that function since you have no other hook than assigning it
> > first to a variable-like thing.
>
> > > Is "recursive function" different
> > > from "non-recursive function" from an implementation point of view?
>
> > Yes. Definitely. With a recursive function you need to be able to call
> > the body of the function that is currently in definition process. This
> > is fundamental different.
>
> No it is not. The underlying structure formed by functions is a graph.

And that tells what? Is your graph not able to represent recursive
relations?

> I can agree that non-recursive functions form tree-like structures -
> but that does *not* matter if you are a language designer. As a
> language designer you are solving the general case - and the general
> case is that functions mimic graphs. The fact that some graphs are
> trees is completely pointless in this case.

Well, the fact that some eggs are cubes is also pointless.

> > Usually functions you want to call are
> > defined already (and be it in C by the header file).
>
> C header files contain *declarations* of functions, not their
> *definitions*.

Later you talk as a "language designer" - a function is defined in
case you know where you have to JuMP to.

> > > Moreover, a function in general does not know at compile-time whether
> > > it is recursive or not, because it can receive a reference to itself
> > > at run-time.
>
> > Bullshit. You are too far from practice.
>
> Oh really? But what about virtual methods in C++, or methods in Java
> which require dynamic binding? Are you implying that it is uncommon
> for a C++ virtual method to "call itself" (albeit in the context of a
> different instance of the C++ class in question). What languages do
> you know besides Forth?

Do we talk about Go or about Java/C++/C#... and so on? I always was
thinking that Go took a specific design layout for good reasons. Get
back to what we are talking about!

> > Of course you can construct
> > recursion by passing function pointers. No doubts… But you can
> > optimize functions where you know they are recursive ;)
>
> You mean tail recursion? If you do, then why didn't you simply wrote
> that you are talking about tail recursion?

I do not want "tail recursion" (that btw. means different things), I
want recursion of a single function. You can do something with "tail
recursion" there if you make an optimizing compiler. The picture in
understanding the language is different.

> > And if you
> > want to bring fundamental logic here: It's not clear in general if not
> > a function is recursive. But you can determine if a function is
> > determinated to be recursive and if a function can in no case be
> > recursive. These cases are the most common.
>
> You are clearly forgetting about dynamic binding, which mostly uses
> pointers to functions (C++, Java, Smalltalk, etc). The Linux kernel
> (implemented in C) also makes a good use of function pointers (in the
> filesystem, in interfaces to modules).

I do not forget this. Did you count, where it calls itself by a passed
pointer? And even this would not be the point. In terms of the
implementor of a language you do not always need to know where
something is recursive. The things have to work. And the same function
passed as pointer as the function that is processed, is arbitrarily
absolutely the same as any other function. This is not true as long as
you have "execution paths" or "execution trees" in the compiler. But a
binary is a binary if you do not have a JIT in place. But even a JIT
does things far from your imagination if you only know the expression
you made in so called "source code".

> > Where you do not know it
> > exactly is where a function gets a pointer to a function and this
> > function pointer is used to call the passed function. In usual
> > programs such a case is uncommon.
>
> I think you are wrong.

That's up to you.

> > > > - at the moment I
> > > > would have to waste a variable(-name) (and pre-declare it) in every
> > > > case to get success. This is useless complexity. As language designers
> > > > you should not too much depend on "Google-deathmatch"-things, where
> > > > always the answer is "yes, but nobody uses it". Nobody can use it in
> > > > case of Go.
>
> > > You are not making any sense.
>
> > You do require that I'm a sense-making machine? Or do you simply not
> > understand what I mean? You could ask me what I mean. That would be
> > more nice than lifting me to the level of a machine that makes sense
> > or makes no sense.
>
> I have no idea what "Google-deatchmacth" means.

OK, I do not know if this still exists - you can compare two search
terms an the one that wins, beats the other (animated). Was
somewhere ;) Maybe I made a typo - not that big thing.

> > > > Here are not only people that played with self-designed
> > > > languages. Here are people that implemented other languages and even
> > > > people that do have no experience with different languages at all (as
> > > > I see some here with loud voices).
>
> > > I wish you expressed your ideas more clearly, because I am not sure
> > > what you mean by this. And I would like to know what do you mean by
> > > this, but cannot decode the meaning of it from the incoherent
> > > sentences you wrote.
>
> > Mhm, please express more clearly what you did not understand. This
> > would help to formulate a more clear message that fits your mind.
>
> I do not understand the whole paragraph.

Go is not the only language out there. It's not even really usable for
bigger projects now. People that talk here either have
1) developed an own language
2) implemented an known language
3) no glue about computer language design

Was that more clear now?

Blabla,
-Helmar

konrad

unread,
Dec 28, 2009, 5:54:32 PM12/28/09
to golang-nuts

On Dec 29, 4:44 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:

> > So the function literals are
> > only interesting as long as they do not use recursion (which should be
> > simpler in Go than in C...).
>
> What are you saying? That it is categorically impossible to implement
> a language in which it is possible to [recursively call an anonymous
> function from within itself]?
>
> As for Go, the fact that Go cannot *currently* do it is only a minor
> problem. It can be fixed, if Go language designers choose so. I have
> no doubts about that.
>

If he is then he's quite wrong. There is a lovely little Lisp called
PicoLisp which has syntax for anonymous recursive functions. basically
recurse is a builtin that takes a variable number of arguments and
causes the current function to be called.

unread,
Dec 28, 2009, 6:44:13 PM12/28/09
to golang-nuts
On Dec 28, 11:14 pm, Helmar <hel...@gmail.com> wrote:
> On Dec 28, 4:34 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > On Dec 28, 8:54 pm, Helmar <hel...@gmail.com> wrote:
>
> > > Hi,
>
> > > On Dec 28, 2:33 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > > > Well, I have beaten you by 23 minutes on this one.
>
> > > Ah, ok, we where in supermarket to buy something and things like this.
> > > I do not want to beat anyone who thinks carefully about something in
> > > terms of "time". This would be too - well - I think too short
> > > thinking.
>
> > I think your analogy is in appropriate. The thing is, in a free market
> > economy, it does not matter whether a person arrives at a supermarket
> > at time T or T+20. The goods, food, etc will always be there waiting
> > for you, since there is a slight oversupply. In a communist economy,
> > or some rural environment without any supermarkets, this may not be
> > the case. But if you are living in a city, this *is* mostly the case.
>
> Do I have more time in communism?

Though I agree that a language designer should thing in absolute terms
(i.e: "timelessly"), I still think your analogy with a supermarket was
invalid.

> [cut]


> > > I can not pass a
> > > local/noname func to another func where the passed func is standalone
> > > (without variable) and uses recursion by itself. You simply can not
> > > call that function since you have no other hook than assigning it
> > > first to a variable-like thing.
>
> > > > Is "recursive function" different
> > > > from "non-recursive function" from an implementation point of view?
>
> > > Yes. Definitely. With a recursive function you need to be able to call
> > > the body of the function that is currently in definition process. This
> > > is fundamental different.
>
> > No it is not. The underlying structure formed by functions is a graph.
>
> And that tells what? Is your graph not able to represent recursive
> relations?

I wish you had cut the crap and just simply had explained why you
wrote that "recursive functions are fundamentally different". I guess
that's not going to happen.

> > I can agree that non-recursive functions form tree-like structures -
> > but that does *not* matter if you are a language designer. As a
> > language designer you are solving the general case - and the general
> > case is that functions mimic graphs. The fact that some graphs are
> > trees is completely pointless in this case.
>
> Well, the fact that some eggs are cubes is also pointless.

Eggs are *not* mathematical objects. Therefore the sentence "some eggs
are cubes" or even the question "are some eggs cubes" is complete
nonsense.

The structures "graph" and "tree" are both mathematical objects.

> > > Usually functions you want to call are
> > > defined already (and be it in C by the header file).
>
> > C header files contain *declarations* of functions, not their
> > *definitions*.
>
> Later you talk as a "language designer" - a function is defined in
> case you know where you have to JuMP to.

Well, but that is only true for compiled languages. On the other hand,
in an interpreted language a function is defined in case you know the
address of [the object which represents the (parsed) function].

> > > > Moreover, a function in general does not know at compile-time whether
> > > > it is recursive or not, because it can receive a reference to itself
> > > > at run-time.

> > > > > Here are not only people that played with self-designed


> > > > > languages. Here are people that implemented other languages and even
> > > > > people that do have no experience with different languages at all (as
> > > > > I see some here with loud voices).
>
> > > > I wish you expressed your ideas more clearly, because I am not sure
> > > > what you mean by this. And I would like to know what do you mean by
> > > > this, but cannot decode the meaning of it from the incoherent
> > > > sentences you wrote.
>
> > > Mhm, please express more clearly what you did not understand. This
> > > would help to formulate a more clear message that fits your mind.
>
> > I do not understand the whole paragraph.
>
> Go is not the only language out there. It's not even really usable for
> bigger projects now. People that talk here either have
> 1) developed an own language
> 2) implemented an known language
> 3) no glue about computer language design

Reaction to point 1: The number of people who are developing languages
from scratch is very low. But that is only my impression, the actual
statistics (if there is one) may be different. The number of people
who are designing/adding individual language features seems to be
greater.

> Was that more clear now?

No. You left out the part in braces.

Helmar

unread,
Dec 29, 2009, 1:54:51 PM12/29/09
to golang-nuts
Hi,

On Dec 28, 5:12 pm, Ian Lance Taylor <i...@google.com> wrote:
> Helmar <hel...@gmail.com> writes:
> > On Dec 28, 4:11 pm, Ben Tilly <bti...@gmail.com> wrote:
> >> On 12/28/09, Helmar <hel...@gmail.com> wrote:
>
> >> >  On Dec 28, 3:05 pm, Ian Lance Taylor <i...@google.com> wrote:
>
> >> >  > We've considered things along those lines, but they don't solve the
> >> >  > problem of mutually recursive function literals.
>
> >> > Maybe I did not understand "mutually recursive". Could you explain it,
> >> >  if that is something special?
>
> >> Mutually recursive functions are a set of functions that call each
> >> other recursively.
>
> > OK, nothing I'm interested to address directly.
>
> But mutually recursive functions are a simple and natural
> generalization of singly recursive functions.  If we add a special
> case to address the latter, why shouldn't we add a special case to
> address the former?  And if we add a special case for the former, it
> should naturally address the latter case.

OK, but the case is you do not have names to address the things. For
your "mutual recursive" cases I do not see any good solution except
naming (and this might be a variable as it is now). To access the
function you are inside by an anonymous accessor would be cool not for
the comfort of not to have to define a variable only but also for
writing code generators. As of now the code generator has to invent
variable names. That's not cool to simply get recursion.

> >> >  > How do other languages address this?
>
> >> > What I most know about is Forth: they have a word called "RECURSE"
> >> >  there, that works for named things and nonames as making the call to
> >> >  the current definition.
>
> I think Forth is kind of a special case, though.

But it is a good model.

>  In Forth a function
> has no name until it is defined, so a RECURSE call is quite useful to
> refer to the function being defined.  And in Forth it's comparatively
> difficult to write mutually recursive functions.

Well, you have something like a doer/defer

doer a
: b a ;
make a b ;

That is not really difficult. Go makes this simpler. But the simple
case of simple recursion of nonames is not possible without
workarounds in Go.

>  In Go ordinary
> functions can of course be both recursive and mutually recursive.  We
> are only talking about function literals here, and Go does make it
> reasonably easy to give function literals a name by using a variable.
> So I don't think the special case of Forth is a very good guide for
> Go.
>
> > Mhm. Assembler can do it too (of course). Someone told that Javascript
> > can do it. Perl can do it too (you've to re-read docs ;) - it's not
> > simple to make but it can be done).
>
> You can't write a recursive call to an anonymous function in
> assembler, except via constructs that are very difficult to use
> correctly like "call . - 20".

Ah, OK. I'd think that local labels are something like nonames, since
I can access them only in a very limited scope of the source.

> In Javascript, you can't call an anonymous function recursively, but
> you can give a function literal a name.  That is, you can write:
>
> var f = function fact(x) { if (x<=1) return 1; else return x*fact(x-1); }
>
> That would be an approach we could use in Go but it also does not
> address the problem of mutually recursive functions.
>
> That said, Javascript also supports "arguments.callee".  That is cheap
> in an interpreted language but not something we are likely to support
> in GO.  In Perl6 you can refer to the &?BLOCK variable, which is
> similar.
>
> Ian

Regards,
-Helmar

Qtvali

unread,
Dec 29, 2009, 2:09:29 PM12/29/09
to golang-nuts
One solution is anonymous inline classes (http://www.developer.com/
java/other/article.php/3300881/The-Essence-of-OOP-using-Java-Anonymous-
Classes.htm).

struct rec2 {
a, b func(rec rec2);
}

q = rec {
func(rec rec2) { rec.b(rec); }
func(rec rec2) { rec.a(rec); }
}

Truls

unread,
Dec 29, 2009, 2:47:53 PM12/29/09
to golang-nuts
On Dec 28, 8:54 pm, Helmar <hel...@gmail.com> wrote:

> You miss the point of the things. It's impossible to even define a
> local func that is recursive without the variable. I can not pass a
> local/noname func to another func where the passed func is standalone
> (without variable) and uses recursion by itself. You simply can not
> call that function since you have no other hook than assigning it
> first to a variable-like thing.

Helmar, I think you are forgetting that closures will actually make
the variable approach work just fine, even when returning the func or
passing it to another function.

The closure will result in a slight overhead, though. Perhaps this
could be optimized away when the function literal is the only thing
that is ever assigned to the variable? I.e. the var is recognized as
constant. Would it be possible to make that work in the mutually
recursive case, Ian?

-Truls

Ian Lance Taylor

unread,
Dec 29, 2009, 4:26:09 PM12/29/09
to Truls, golang-nuts
Truls <truls....@gmail.com> writes:

> The closure will result in a slight overhead, though. Perhaps this
> could be optimized away when the function literal is the only thing
> that is ever assigned to the variable? I.e. the var is recognized as
> constant. Would it be possible to make that work in the mutually
> recursive case, Ian?

It's a well understood compiler optimization--interprocedural constant
propagation--but not one that 6g/8g currently do. gccgo can do it in
general but I haven't checked whether it will do it in this specific
case.

Ian

Qtvali

unread,
Dec 29, 2009, 6:31:01 PM12/29/09
to golang-nuts
What is wrong with:
var b func();
a = func() {
b();
}
b = func() {
a();
}

As they are both lambdas, this should work as well?

Qtvali

unread,
Dec 29, 2009, 6:33:30 PM12/29/09
to golang-nuts
And, btw., if you are meaning some kind of optimization used by
functional languages - I rather doubt if imperative languages have
anything to do with it. You can simply use loops in most cases.

unread,
Dec 30, 2009, 7:24:20 AM12/30/09
to golang-nuts
On Dec 29, 7:54 pm, Helmar <hel...@gmail.com> wrote:
> Hi,
>
> On Dec 28, 5:12 pm, Ian Lance Taylor <i...@google.com> wrote:
>
> > I think Forth is kind of a special case, though.
>
> But it is a good model.

Maybe unrelated to the matter at hand (namely: recursion), but maybe
important as a general note:

I doubt that an untyped language (=Forth) can be a good model for
implementing a strictly typed language (=Go). Similarly, I doubt that
someone who only has experience implementing a compiler of the former
kind can be trusted enough to be able to implement a compiler of the
latter kind. It is no coincidence that the number of scripting/
interpreted languages seems to be greater than the number of compiled
languages - the former are just easier to implement and are easier on
the IQ of the people who are developing them. That said, if an
interpreted language is well established and does not change much
(e.g: Python, Bash, etc), then it should have a JIT compiler. It is
very unfortunate that many established interpreted languages have no
JIT (pretty stupid, I think). I hope stable version of "unladen
swallow" will be available as soon as possible.

Helmar

unread,
Dec 30, 2009, 9:11:37 AM12/30/09
to golang-nuts
Hi,

You can see it from another point of view: Forth has the strictest
type safety you can think of. There are only integers and floats in a
default installation. Every other type has to be expressed in int or
floats. Well, uints are a little bit unwise as they are implemented,
but that is caused by simplicity. To make this more clear: for example
a "pointer" is simply an integer index to a memory cell. What that
really means is depending on the implementation. Well, again: Forth
has the simplest and safest type system you can think of. Usually
everything is int. Floats are even only an option and could be
expressed as ints as well (while not actual system does it do so).
Since you only have that one (or optionally two) types, everything is
safely bound to that one master type. Every other type is intention of
the programmer. Even an XT (execution token) is basically an int
value. That usually means a "pointer" but it also could be an index to
a XT-table that contains the real pointers.

I do not know what you mean with "interpreted". Forth is not
interpreted. It compiles in every case if it extends the system. Well,
older or simpler systems compile to some intermediate language that is
"interpreted" by the system (usually something that is "threaded
code"). But more common today are simple "native-code-generators" that
do loophole-optimization or also JIT-compilers that use the
intermediate representation to build native code. In commercial
products there are flow-analyzing compilers that take an execution
path/tree and build what they think is optimal as native code. From
the users point of view all that currently existing (and recognized)
Forth-systems are work similar to an interpreter. This is nice for
incremental development, which makes living with one strictly forced
data type that possible as it is in Forth. Well, Forth is one of the
languages with most implementations out there. This did not
fundamentally change the way how Forth works. I'd be silent from a C-
derivate point of view, since most of these language have a reference-
implementation only and may be one or two other implementations that
do not do everything of the "original". C is a special case in this
regard and the reason why we still use C for some tasks (as the
implementors of Go that used the Plan9 C-toolchain).

Regards,
-Helmar

unread,
Dec 30, 2009, 11:14:23 AM12/30/09
to golang-nuts
On Dec 30, 3:11 pm, Helmar <hel...@gmail.com> wrote:
> Hi,
>
> On Dec 30, 7:24 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > Maybe unrelated to the matter at hand (namely: recursion), but maybe
> > important as a general note:
>
> > I doubt that an untyped language (=Forth) can be a good model for
> > implementing a strictly typed language (=Go). Similarly, I doubt that
> > someone who only has experience implementing a compiler of the former
> > kind can be trusted enough to be able to implement a compiler of the
> > latter kind. It is no coincidence that the number of scripting/
> > interpreted languages seems to be greater than the number of compiled
> > languages - the former are just easier to implement and are easier on
> > the IQ of the people who are developing them. That said, if an
> > interpreted language is well established and does not change much
> > (e.g: Python, Bash, etc), then it should have a JIT compiler. It is
> > very unfortunate that many established interpreted languages have no
> > JIT (pretty stupid, I think). I hope stable version of "unladen
> > swallow" will be available as soon as possible.
>
> You can see it from another point of view: Forth has the strictest
> type safety you can think of.

I do not know whether you are joking or something. If not, then it is
very very sad.

> There are only integers and floats in a
> default installation. Every other type has to be expressed in int or
> floats. Well, uints are a little bit unwise as they are implemented,
> but that is caused by simplicity.

Maybe you are confusing [simplicity of implementing the language] with
[simplicity of using the language].

Then there is also one other thing: the simplicity of predicting [what
can and what cannot happen while the program is running] before you
actually run the program.

> To make this more clear: for example
> a "pointer" is simply an integer index to a memory cell.

That is also applicable to other languages, like Java for example in
which references are implemented in the VM by means of integers. The
distinction is what you are allowed to do with that integer as a
programmer and what you are not allowed to do.

> What that
> really means is depending on the implementation. Well, again: Forth
> has the simplest and safest type system you can think of.

If you were responsible for the safety of cars, we would all be dead
by now. I'm sure of it.

> Usually everything is int.

Well, usually every program is a Turing machine. Does this knowledge
help? No, it doesn't.

> Floats are even only an option and could be
> expressed as ints as well (while not actual system does it do so).
> Since you only have that one (or optionally two) types, everything is
> safely bound to that one master type. Every other type is intention of
> the programmer.

... or an intention of a language designer. Whoops, that would mean
that such a language has support for other types than plain integers.
Naaa, that cannot be. Therefore ... I hereby decree that language
designers cannot have intentions. Those who do happen to have some,
should be imprisoned so that they do not contaminate the society with
their crazy minds.

> Even an XT (execution token) is basically an int
> value. That usually means a "pointer" but it also could be an index to
> a XT-table that contains the real pointers.
>

> Well, Forth is one of the
> languages with most implementations out there.

The most likely explanation is that it is caused by the fact that one
does not need a high IQ or investments (time, money) to implement a
Forth system.

Analogy: Do you know why there live so many people on earth, but no
androids? Because fucking and having babies is one of the most trivial
tasks one can think of, but the construction of an artificial being is
beyond our understanding.

> This did not
> fundamentally change the way how Forth works.

Are you saying that you can simply take *any* program runnable in one
implementation of Forth and except it to flawlessly run in another
implementation of Forth? What if one implementation is able to paint
onto the screen and the other cannot?

> I'd be silent from a C-
> derivate point of view, since most of these language have a reference-
> implementation only and may be one or two other implementations that
> do not do everything of the "original". C is a special case in this
> regard and the reason why we still use C for some tasks (as the
> implementors of Go that used the Plan9 C-toolchain).

I suppose any implementation of C can do addition in exactly the same
way as any other implementation of C. Why am I talking about addition?
Well, because I had to strip C from all capabilities which are beyond
Forth's level.

Helmar

unread,
Dec 30, 2009, 12:29:00 PM12/30/09
to golang-nuts
Hi,

> > To make this more clear: for example
> > a "pointer" is simply an integer index to a memory cell.
>

> That is also applicable to other languages, like Java for example in ...

And like in Java (you really can there?) it's possible in Forth to
implement the checks. That is up to you as the programmer.

> > Well, Forth is one of the
> > languages with most implementations out there.
>
> The most likely explanation is that it is caused by the fact that one
> does not need a high IQ or investments  (time, money) to implement a
> Forth system.

Well, a little bit of racist says the rats here in his house do not
have an IQ and never implemented a Forth. The investment to implement
*and* use Forth is only time and fundamental knowledge what happens
and what can be done. Forth is something about how to reduce
complexity. You can not do that without thinking. And it takes times
and can be a big investment in terms of money if you pay someone.

You did not note that Forth is such an old language. The other
explanation is that is does not need much resources in terms of
machine to be implemented (hehe, 32K are a lot of memory).

Btw.? Did you ever implement one? That would help you to respect such
a work and see what happens if you would do...

-Helmar

Tom Abernathy

unread,
Jan 1, 2010, 1:55:52 AM1/1/10
to golang-nuts
I am totally at a loss to understand why you thin that recursion to
function literals is an important topic.
Why would someone define an function as a literal if they needed to
reference the function?
What advantage is gained by programming in this manner?
Is it a performance issue (speed or code size?) ?
Does is simplify the code? If so, how? For maintenance? For
reusability?

Helmar

unread,
Jan 1, 2010, 3:42:38 AM1/1/10
to golang-nuts
Hi,

On Jan 1, 1:55 am, Tom Abernathy <tom.aberna...@gmail.com> wrote:
> I am totally at a loss to understand why you thin that recursion to
> function literals is an important topic.

why programming is important? I never had to program my mobile phone
to get it working. There always was software with it.

> Why would someone define an function as a literal if they needed to
> reference the function?

That function is always referenced - and be it by the pointer that
references the function.

> What advantage is gained by programming in this manner?
> Is it a performance issue (speed or code size?) ?
> Does is simplify the code? If so, how? For maintenance? For
> reusability?

About all of it. It's simpler to understand if you have a hint that
there is recursion involved (when reading the source you do not need
to remember what variable this func is assigned to and so on).
Also say you want to have an array or map of anonymous functions. If
one or more of these functions should be recursive, it's a not so nice
task to always have to define variables and keep track of what is what
and calls what. Say you also want to write a source code generator -
you are about to loose the ability to use recursion in such
environments. I have for something like a Postscript-like interpreter
things like

var Ops = map[string]func(t *CharMapperI){
"begin": func(t *CharMapperI) {
a := t.St.Pop()
_ = a
},
"beginbfchar": func(t *CharMapperI) {
t.Args = t.St.Drop(1)
t.Marker = t.St.Depth()
},
"beginbfrange": func(t *CharMapperI) {
t.Args = t.St.Drop(1)
t.Marker = t.St.Depth()
},
"begincidchar": func(t *CharMapperI) {
t.Args = t.St.Drop(1)
t.Marker = t.St.Depth()
},
...

They are as of now generated by a code generator. I would probably
like to use recursion with some of the funcs. But it would look like a
bad hack (as it is in fact).

Recursion is a basic programming facility and Go did a good job for
named funcs. It simply missed the simple recursion of function
literals (aka nonames) by concept as of now. Well, it might be I'm
wrong and recursion is something completely useless.

Regards,
-Helmar

PS: Happy new year!

befelemepeseveze

unread,
Jan 1, 2010, 5:37:49 AM1/1/10
to golang-nuts
On 1 led, 09:42, Helmar <hel...@gmail.com> wrote:

> About all of it. It's simpler to understand if you have a hint that
> there is recursion involved (when reading the source you do not need
> to remember what variable this func is assigned to and so on).

Declaring a named function is more or less the same as once only
assigning a function literal to a (top level) variable of the same
name. Is it also simpler to not to need to remember the identifiers of
named functions?

> Also say you want to have an array or map of anonymous functions. If
> one or more of these functions should be recursive, it's a not so nice
> task to always have to define variables and keep track of what is what
> and calls what.

Why variables, why not the usual named functions? You can put those in
a map/vector too.

> Recursion is a basic programming facility and Go did a good job for
> named funcs. It simply missed the simple recursion of function
> literals (aka nonames) by concept as of now. Well, it might be I'm
> wrong and recursion is something completely useless.

I think that completely useless is to insist on using only function
literals in a situation where they can't do what you want instead of
creating named functions which would be IMO a pretty natural choice.
Also you get for free the recursion capabilities you would like to
have. I fully respect your right to choose your coding style, but for
me it's a very confusing one. And I don't think it's needed to extend
the language just to support such, in my eyes, oddities.

Qtvali

unread,
Jan 1, 2010, 10:08:47 AM1/1/10
to golang-nuts
> That function is always referenced - and be it by the pointer that
> references the function.

But if unnamed functions are declared in local namespace, why can't
you use predeclaring variable anyway?

> PS: Happy new year!

To you too!

Russ Cox

unread,
Jan 2, 2010, 8:05:35 PM1/2/10
to Truls, golang-nuts
> The closure will result in a slight overhead, though. Perhaps this
> could be optimized away when the function literal is the only thing
> that is ever assigned to the variable? I.e. the var is recognized as
> constant. Would it be possible to make that work in the mutually
> recursive case, Ian?

Even if the var is constant in one invocation of a function,
there is still a closure to make, because the var may be
different on other invocations of the function.

If mutually recursive function literals are so important
in your programs that the current work-around of
naming the literals does not suffice, then I suspect
Go is not the language for you.

Russ

Russ Cox

unread,
Jan 2, 2010, 8:06:08 PM1/2/10
to Marcin 'Qrczak' Kowalczyk, golang-nuts
> I consider a tab width different than 8 as evil because it's

Claiming that particular tab widths are "evil"
is at best hyperbole and at worst an attempt to move away
from logical arguments into irrational ones.

> impractical to configure every tool which displays code for a custom
> tab width, and 8 is the most common default. Since an indent of 8
> spaces is too big, it follows that code should not use tabs for
> indentation. It's a pity that Go went this way.

It only follows that code should be written so that it displays
well no matter what tab width is used. One way is to avoid
tabs altogether, as you suggest. Gofmt shows another way:
it uses tabs for left indentation but is careful not to assume
a particular tab width, so the interior alignment is correct
no matter what tab width is used.

Russ

unread,
Jan 5, 2010, 7:01:18 AM1/5/10
to golang-nuts
On Dec 30 2009, 6:29 pm, Helmar <hel...@gmail.com> wrote:
> Hi,
>
> > > To make this more clear: for example
> > > a "pointer" is simply an integer index to a memory cell.
>
> > That is also applicable to other languages, like Java for example in ...
>
> [cut] it's possible in Forth to implement the checks. That is up to you as the programmer.

Well, but that's the whole point: Forth does *not* by itself have
those features you are attributing to it. It does not have local
variables, types other than ints&floats, closures, pure functions,
etc.

It is not about what is *possible* to implement a particular feature
in a programming language - it is about whether the language actually
supports "out of the box". If I were to imply your logic to other
languages, then it would look like this:

A1: an assembly language: it is possible to implement local variables
and functions.
A2: Java: it is possible to implement List<byte> consuming only N
bytes of memory, where N is the size of the list.
A3: the C language: it is possible to implement Smalltalk-like
objects.
A4: Smalltalk: it is possible to implement compile-time type checking.

How? Like this, of course:

B1: grab the source code of the assembly-language compiler and add
support for local variables and functions.
B2: grab the sources of some JVM implementation and add better support
for generic types.
B3: grab the sources of GCC and introduce the concept of a Smalltalk-
like object.
B4: grab the sources of Squeak and change the language&compiler so
that it is possible to perform type checking.

So, you see, piece of cake. No problems here, any existing language
can be changed to support any kind of new feature.

But it is a total "perversion" to think like this. It is clear that
those languages to *not* support the mentioned features. It may
surprise you, but I do *not* want to apply this "perverted" style of
thinking to Forth. More specifically, the truth is the following:

- Forth does *not* have support for local variables
- Forth does *not* have implement any type system (except for the type
system "everything is an integer" - but that is clearly not a
sophisticated type system at all)
- Forth does *not* have compile-time type checking
- Forth does *not* have support for user-defined structures or objects
- etc

> > > Well, Forth is one of the
> > > languages with most implementations out there.
>
> > The most likely explanation is that it is caused by the fact that one
> > does not need a high IQ or investments  (time, money) to implement a
> > Forth system.
>
> Well, a little bit of racist says the rats here in his house do not
> have an IQ and never implemented a Forth. The investment to implement
> *and* use Forth is only time and fundamental knowledge what happens
> and what can be done. Forth is something about how to reduce
> complexity.

1. Complexity of what?
2. Maybe you heard about the "there is no free lunch" rule.

> You can not do that without thinking. And it takes times
> and can be a big investment in terms of money if you pay someone.
>
> You did not note that Forth is such an old language. The other
> explanation is that is does not need much resources in terms of
> machine to be implemented (hehe, 32K are a lot of memory).
>
> Btw.? Did you ever implement one? That would help you to respect such
> a work and see what happens if you would do...

No, I did not. The only thing I find interesting about Forth is that
it implements a unique and different compilation strategy from other
languages. Maybe I am repeating myself, but I am *not* considering
features like local variables or type checking to be a part of Forth -
those language features exist *outside* of the Forth language.

Helmar

unread,
Jan 5, 2010, 2:54:29 PM1/5/10
to golang-nuts
Hi,

On Jan 5, 7:01 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> On Dec 30 2009, 6:29 pm, Helmar <hel...@gmail.com> wrote:
>
> > Hi,
>
> > > > To make this more clear: for example
> > > > a "pointer" is simply an integer index to a memory cell.
>
> > > That is also applicable to other languages, like Java for example in ...
>
> > [cut] it's possible in Forth to implement the checks. That is up to you as the programmer.
>
> Well, but that's the whole point: Forth does *not* by itself have
> those features you are attributing to it. It does not have local
> variables,

You are wrong. Locals are part of the ANS standard.

Why does Forth not support it? You have libraries. Most commercial
Forths do have configurations that support a lot of the things out of
the box.

> It may
> surprise you, but I do *not* want to apply this "perverted" style of
> thinking to Forth. More specifically, the truth is the following:
>
> - Forth does *not* have support for local variables

You are wrong, as I told you. This is written in the ANS standard.

> - Forth does *not* have implement any type system (except for the type
> system "everything is an integer" - but that is clearly not a
> sophisticated type system at all)

Well, more sophisticated things out there. Ask you favorite searching
machine...

> - Forth does *not* have compile-time type checking

Again, take a look beside what you know as "Forth". There hundreds of
it.

> - Forth does *not* have support for user-defined structures or objects

This is wrong. Forth had Object support before OOP was invented.

: foo create , does> ... ;

if you know what I mean. You can take a look at how much you would
need to extend this by looking at the work of Bernd Paysan and his
Mini-OOF: http://www.jwdt.com/~paysan/screenful.html

> - etc

^^ This is wrong. It's inside the ANS standard.

> or type checking to be a part of Forth -
> those language features exist *outside* of the Forth language.

No. It's not "outside".

-Helmar

unread,
Jan 6, 2010, 7:16:09 AM1/6/10
to golang-nuts
On Jan 5, 8:54 pm, Helmar <hel...@gmail.com> wrote:
> Hi,
>
> On Jan 5, 7:01 am, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
>
> > On Dec 30 2009, 6:29 pm, Helmar <hel...@gmail.com> wrote:
>
> Why does Forth not support it? You have libraries. Most commercial
> Forths do have configurations that support a lot of the things out of
> the box.
>
> > It may
> > surprise you, but I do *not* want to apply this "perverted" style of
> > thinking to Forth. More specifically, the truth is the following:
>
> > - Forth does *not* have support for local variables
>
> You are wrong, as I told you. This is written in the ANS standard.
>
> > - Forth does *not* have implement any type system (except for the type
> > system "everything is an integer" - but that is clearly not a
> > sophisticated type system at all)
>
> Well, more sophisticated things out there. Ask you favorite searching
> machine...

You don't seem to be willing understand what I am saying. I am *not*
denying there somewhere in the wild exists [a Forth word set
implementing compile-time type checking]. In the same way, I am *not*
denying that there potentially somewhere exists an implementation of
the C language which for example has explicit support for pure
functions, transactional memory, tuples, or some functional
programming features.

If you are applying certain logic when you are talking about Forth
libraries extending the language, why should I be denied to apply the
very same logic to *other* languages? Can you explain to me why should
I be prohibited from applying it, say, the C language? If C does not
have language feature X, then I can potentially add it to C. By your
logic, it would still be C - even if I removed some C features. Maybe
I am repeating myself, but this kind of logic is a "perversion", it
entails a drastic redefinition of the meaning of the term "programming
language". Why are you even using this term in conjunction with Forth?
Wouldn't another term be more useful and more accurate?

"Forth" is not equivalent to "Object-oriented Forth".
Contrary to this, "C++" is equivalent to "Object-oriented C++".

Or does you mind fail to recognize the essential difference in the
meaning of the above two sentences?

> > - Forth does *not* have compile-time type checking
>

> .Again, take a look beside what you know as "Forth". There hundreds of
> it.

Again, take a look beside what you know as "C". People made hundreds
of extensions to the C language ... well, nobody uses them, but that
does not matter. It only matters, by your logic, that they exist -
somewhere, somewhere out there, in the cyberspace of the internet.
Never heard of them? Just search the net. It's so simple.

Reply all
Reply to author
Forward
0 new messages