An important proposal will fail without your support

348 views
Skip to first unread message

Jon Perryman

unread,
Mar 10, 2020, 1:31:33 PM3/10/20
to golang-nuts
If proposal https://github.com/golang/go/issues/37292 fails, everyone will lose out on a great opportunity. API's can be greatly simplified. Writing pre-processors and GO generate don't completely meet our truly meeting our needs. Is the extra implementation work worth the effort? Do we live with mediocre solutions to avoid repetition? Why do we live with mediocre solutions because we don't have compile time logic? Please consider "like" of this proposal otherwise we will miss this great opportunity.

There are many examples where compile time flexibility is important. Consider the adverse effect of GO limitations has had on the very important GNU GETTEXT( ) - native language support (multi-lingual messages and localization):
  • Documentation is 17 chapters -> https://www.gnu.org/software/gettext/manual/gettext.html
  • Big-o complexity o(n^2)!!!
  • It has several important utilities for maintaining translation catalogs.
  • Hundreds of developer's were involved in its design and Implementation. They came up with the best implementation considering they don't have a compile time language.
  • Use and maintenance is labor intensive and time consuming .
fmt.Println( gettext( fmt.Sprintf("message text at %v with %v bytes", time.format( ), number) ) )

When to implement Gettext( ) is a difficult decision and lots of work early in your project. As you can see, gettext( ) is a function call with the message to be translated. The message must contain everything to be translated. After determining the language and localization, gettext searches for a matching message translation rule in the language specific catalog. The rule is applied to the message and data needing localization is converted (e.g. dates, numbers, currency).

fmt.Println( #gettext( "message text at %t with %n bytes", time, number ) )
   
or
fmt
.Println( #gettext( msgid="jon001", time, number ))

Isn't this cleaner and easier to code. Just as important,  the big-o complexity goes to  o(n)!!! We could make this even easier by creating a #gettext.println( )

You won't see the #gettext() function unless you are the maintainer of this functionality. Function #gettext( ) is small and easy to maintain. One possible implementation for #gettext( ) with this proposal gives you lots of flexibility and eliminates 90% of the code in the real GNU gettext( ). 

func #gettext( args Args ) {
    src
:= "gettext("         // call real gettext function
    current_positional_arg
:= 1
   
if args.msgid != nil {    // keyword argument "msgid" not specified
        src
+= args.msgid + " ,nil"
   
} else {
        src
+= "nil, " + args.positional[1]
        current_positional_arg
:= 2
   
}
   
for ; current_positional_arg <= args.positional.length; current_positional_arg {
        arg
= args.positional[current_positional_arg]
       
if reflect.TypeOf(arg) == "time.Time" {
            src
+= ",gettext.TimeLocal(" + arg + ")"
       
} else if reflect.TypeOf(arg) == "int" {
            src
+= ",gettext.Number(" + arg + ")"
       
} else {
            src
+= "," + arg
       
}
   
}
    compiler
.AddStatement(*,src)   // replaces the #gettext( ) with real code
}

This compiler called function replaces the #gettext( ... ) as follows:

#gettext(msgid="jon001", number, time)
    would be replaced
with
gettext
("jon001", nil, gettext.Number(number), gettext.TimeLocal(time) )

The new gettext( ) is greatly simplified. Messages are now in a easily accessible GO module. There arel language specific message modules that are dynamically loaded as needed. E.g. en_jon.go where en is an English message module and jon is the first part of the message id (e.g. jon001). Gettext( ) gets the message rule 001 from en_jon.go and applies the rule to the message. 

It's important that the language specific message modules are simple to edit by language translators. It also needs to be as similar as possible to the GNU standard while having GO syntax.

#msg( language=en, prefix=jon )   // english messages jon###

//  translator-comments
//  extracted-comments
// reference…
// flag…
#msg(
    id
=001,                   // msg id jon001
    msgstr
[0]="message text at %t with %n bytes",
   
...
    msgstr
[N]="message text at %t with %n bytes"
)


//  translator-comments
//  extracted-comments
// reference…
// flag…
#msg(
    id
=002,     // message id jon002
    msgstr
[0]="message text at %t with %n bytes",
   
...
    msgstr
[N]="message text at %t with %n bytes"
)


//  translator-comments
//  extracted-comments
// reference…
// flag…
#msg(
    id
=003,        // message id jon003
    msgstr
[0]="message text at %t with %n bytes",
   
...
    msgstr
[N]="message text at %t with %n bytes"
)

Using the #msg( ) function hides the complexity of the real GO code to make this easy for translators to maintain.
 
A compile time language has many more benefits that are not obvious. I strongly urge everyone to like proposal https://github.com/golang/go/issues/37292 .

Thanks, Jon.

Thomas Bushnell, BSG

unread,
Mar 10, 2020, 1:39:38 PM3/10/20
to Jon Perryman, golang-nuts
In C it's called _.

While it's not normally considered good Go style, you could use a "." import of the package, and call the function G.

Then: "fmt.Println(G("message text at %t with %n bytes"), time, number)

Notice that (following C) the gettext lookup function is called with the string, and not with extra arguments.

Seems fine to me. Needs no language changes.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/2325901c-906e-4977-a989-5e0c00297052%40googlegroups.com.

Brian Candler

unread,
Mar 10, 2020, 2:14:33 PM3/10/20
to golang-nuts
On Tuesday, 10 March 2020 17:31:33 UTC, Jon Perryman wrote:
If proposal https://github.com/golang/go/issues/37292 fails, everyone will lose out on a great opportunity.

This is not a proposal, as it specifies neither the syntax nor the semantics.  I therefore down-voted on that basis alone.
 

This compiler called function replaces the #gettext( ... ) as follows:

#gettext(msgid="jon001", number, time)
    would be replaced
with
gettext
("jon001", nil, gettext.Number(number), gettext.TimeLocal(time) )


That looks like a macro.  But the issue says "Don't confuse this with C macro's nor code generators. Nor is this an alternative for functions."  You've said what it isn't, but not what it is.

In the above example, what does the definition of the #gettext entity look like?

Is it run at compile time, and the *output* of the macro is Go source code or AST which is inserted at the call point?  In that case it's a code generator.

Or is it just an in-place substitution of one form with another, i.e. a templated substitution in the AST? (Macro)

I'd suggest the best way to take this forward would be:
1. Make an initial implementation as a front-end preprocessor to go
2. Let people review the resulting syntax and semantics in practice, when you can give concrete examples

You might find it integrates nicely with the go generate mechanism.

Axel Wagner

unread,
Mar 10, 2020, 2:18:04 PM3/10/20
to Jon Perryman, golang-nuts
Hi Jon,

first, I want to be open and say that I agree with what has been said by others in the issue discussion. I don't think this is a good idea, for all the reasons Ian and Robert gave.

On Tue, Mar 10, 2020 at 6:31 PM Jon Perryman <jon.pe...@gmail.com> wrote:
There are many examples where compile time flexibility is important. Consider the adverse effect of GO limitations has had on the very important GNU GETTEXT( ) - native language support (multi-lingual messages and localization):

I don't really understand your example. gettext is a C software, written long before Go existed. I don't see how any limitations (perceived or real) of Go could have any effect on it.
AIUI you then go into some length of describing a fictional i18n/l10n API and its drawbacks. However, are you aware of https://godoc.org/golang.org/x/text/message, which is a non-fictional such API for Go?
It's certainly not perfect, but at least as far as I can tell, it seems to solve the problems you are having in a far more convenient and readable way than what you are suggesting.
--

Brian Candler

unread,
Mar 10, 2020, 2:21:34 PM3/10/20
to golang-nuts
Sorry, somehow I scrolled over the definition of func #gettext.  So: this function emits literal source code text to be inserted into the compilation point.

There are interesting semantic implications here: the args can't be evaluated at compile time (unless they are constant expressions), but need to be passed as strings representing the expression plus a type.

Michael Jones

unread,
Mar 10, 2020, 2:35:09 PM3/10/20
to Brian Candler, golang-nuts
I wrote some very efficient math software in Go. To accomplish my goals, I used make and awk programs that generate assembly code tuned to the exact demands of command line make configuration. Then it builds in go, then runs. 

This is not mainstream, but has worked well since Go 1.0. It never seemed to me that it was something everyone needs, so that means it being “worse” for me but simpler for a million others might be a reasonable trade off. 

Is there anything of this kind at play here? Can it not be done perfectly using m4, or cpp, or ...

On Tue, Mar 10, 2020 at 11:21 AM Brian Candler <b.ca...@pobox.com> wrote:
Sorry, somehow I scrolled over the definition of func #gettext.  So: this function emits literal source code text to be inserted into the compilation point.

There are interesting semantic implications here: the args can't be evaluated at compile time (unless they are constant expressions), but need to be passed as strings representing the expression plus a type.

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

Jon Perryman

unread,
Mar 10, 2020, 8:10:04 PM3/10/20
to golang-nuts
Everyone needs to like proposal https://github.com/golang/go/issues/37292.The following response proves the importance of a compile time language.

>  In C it's called _.  
> Then: "fmt.Println(G("message text at %t with %n bytes"), time, number)
> Notice that (following C) the gettext lookup function is called with the string, and not with extra arguments.
> Seems fine to me. Needs no language changes.

One key feature is simplification. This isn't simple when an experienced gettext( ) and GO developer can't code it correctly.

1. Placing time and number are outside gettext() means they are not localized. Does fmt.Println( time.Now, 1000.55) display something you want in a message? 

2. Placing time and number in the message text requires it be in a form gettext can identify. I doubt they are supported so you must find a compatible format. Time for more documentation. 

3. The actual statement is fmt.Println( G( fmt.Sprintf( "message text at %v with %f bytes",  time.format(??), number).

Most people do not understand the importance and capabilities that a compile time language would bring to GO. For instance, the cpu overhead was ignored here.

This proposal is not specific to gettext. A compile time language is a must and should be on GO's radar because many API's would benefit. This is a feature that will radically improve GO with little effort. You should "like" this proposal to let them know it's important. 

Thanks, Jon.

Jon Perryman

unread,
Mar 11, 2020, 1:23:22 AM3/11/20
to golang-nuts
Is there anyone who dislike's this proposal able to describe an acceptable implementation of gettext in GO? The concept is simple. Convert a message into another language including date, numbers, day of week, and plurals.

The current gettext:
1. is a CPU hog and intolerable for a large number of messages.
2. is not simple for a beginner.
3. has utilities that must be run (think go generate)

The question is: what does message translation look like for GO (even if it's not GNU gettext compatible)?

Everyone should "like" proposal https://github.com/golang/go/issues/37292 because compile time language is indispensable in compilers with this feature. I've personally developed many API's using this feature. My partial implementation of gettext is 700 lines plus a couple hundred lines for the various conversions (e.g. date formats) in other modulesA full implementation would be a couple thousand lines at most. By comparison, gettext is 115MB with 1500 files.

We are so accustomed to bloated and labor intensive API's, that no one thinks it's a bad thing. A compile time language creates better and more readable code when used properly.

Jon.

Tamás Gulácsi

unread,
Mar 11, 2020, 1:39:36 AM3/11/20
to golang-nuts
Hi Jon,

Have you read https://godoc.org/golang.org/x/text/message ?

It's not gettext, but a better - though not perfect - solution for this i18n problem.

Levieux Michel

unread,
Mar 11, 2020, 3:24:22 AM3/11/20
to Tamás Gulácsi, golang-nuts
Hi Jon,

It seems you missed something here. "Please like my proposal or everyone loses" is not an argument. We don't work that way here. You have suggested the language needs a feature, and have gotten many answers from people that think it does not.
Keeping on repeating the same argument forever will do nothing. Maybe there is a real need for your change but in this case it looks like you need more (different...) examples, and maybe a better approach.

But remember, when a lot of people tell you the same thing, if the only reason you think of is "they don't see what I can see", first it *looks* pretentious to the reader, and second, maybe, just maybe, you missed a point. :)

Have a nice day.

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

miha.v...@gmail.com

unread,
Mar 11, 2020, 4:09:08 AM3/11/20
to golang-nuts
AFAIK this doesn't work in recent go versions and even less if you are using modules.

Dan Kortschak

unread,
Mar 11, 2020, 4:40:36 AM3/11/20
to miha.v...@gmail.com, golang-nuts
Why do you say that?

~/src/golang.org/x/text/message [master*]$ go env GO111MODULE
on
~/src/golang.org/x/text/message [master*]$ go version
go version go1.14 linux/amd64
~/src/golang.org/x/text/message [master*]$ go test
PASS
ok golang.org/x/text/message 0.024s
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e700071c-1138-439c-83c5-93eac98ecb0f%40googlegroups.com
> .


miha.v...@gmail.com

unread,
Mar 11, 2020, 4:58:48 AM3/11/20
to golang-nuts

And I cannot find the issue, but there are a few with extract command not working and crashing.

On Wednesday, March 11, 2020 at 9:40:36 AM UTC+1, kortschak wrote:
Why do you say that?

~/src/golang.org/x/text/message [master*]$ go env GO111MODULE
on
~/src/golang.org/x/text/message [master*]$ go version
go version go1.14 linux/amd64
~/src/golang.org/x/text/message [master*]$ go test
PASS
ok          golang.org/x/text/message        0.024s


On Wed, 2020-03-11 at 01:08 -0700, miha.v...@gmail.com wrote:
> AFAIK this doesn't work in recent go versions and even less if you
> are using modules.
>
> On Wednesday, March 11, 2020 at 6:39:36 AM UTC+1, Tamás Gulácsi
> wrote:
> > Hi Jon,
> > Have you read https://godoc.org/golang.org/x/text/message ?
> > It's not gettext, but a better - though not perfect - solution for
> > this i18n problem.
>
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to golan...@googlegroups.com.

Dan Kortschak

unread,
Mar 11, 2020, 5:02:11 AM3/11/20
to miha.v...@gmail.com, golang-nuts

Jon Perryman

unread,
Mar 13, 2020, 12:48:17 AM3/13/20
to golang-nuts
On Wed, Mar 11, 2020 at 12:23 AM Levieux Michel <mlevi...@gmail.com> wrote
> It seems you missed something here. "Please like my proposal or everyone loses" is not an argument.

No one has debated the power, importance and virtues of my proposal.  Apparently you didn't read the comments in the proposal. The discussion is about why they can't be bothered. Maybe enough likes would motivate a discussion of the merits instead of perceived risks that apparently can't be solved by a good developer.

On Wed, Feb 19, 2020 at 9:17 AM Robert Griesemer <notifi...@github.com> wrote:
> An integrated compile-time language makes a compiler essentially programmable; 
> there's no question that this would be very powerful. 

This comment is from the proposal. Not one person has disagreed with "very powerful". If you disagree, please say why? How is this not far more powerful than GO GENERATE, pre-processors and macro's?

Why isn't a very powerful feature important to everyone? Shouldn't the compiler developers spend more than 5 minutes consideration on very powerful features before they dismiss them? Isn't this proposal worth a "like" just to consider if it's possible?

This proposal is failing because of fear that we will repeat the mistakes of the past. Great developer's will ask how a powerful feature can be made safe in their product instead of finding excuses not to consider it. "liking" a proposal doesn't mean it will be implemented. Instead, it tells developer's  it's important to you and try to find a way to implement that feature. 

On Wed, Feb 19, 2020 at 9:17 AM Robert Griesemer <notifi...@github.com> wrote: 
 >  It's unclear to me how flexible an approach you are envisioning.  

My vision doesn't matter. This must be a team vision. I have a lot of experience with this so I know what works and what fails. I know how to address many of the fears mentioned.

On Tue, Feb 25, 2020 at 2:57 PM Ian Lance Taylor <notifi...@github.com> wrote:
> This proposal is incomplete  

Robert put the proposal best: make GO programmable at compile time. Everything else in the proposal demonstrates possibilities and justifies the value of the proposal. Anything beyond this is a waste of my time at this point.

> I made a similar proposal at #32620  hygienic macros

Not similar and this should not be allowed. The only part of the AST affected would be the #xxx( xxx ) which would be replaced with the generated code. 

> turing complete

These issues have been addressed in other compilers. These issues can be addressed.

because they slow down the compile times,

Compile time is not affected if #xxx( xxx ) is not used in the code. Does GO GENERATE or pre-processors save compile time by reading the source twice? Are they able to produce results as a programmable GO?

do not follow the simplicity and design goals of Go

Why  is this impossible to be part of the requirements?

Choose a compile time language. Possibly GO, Python, Java, NodeJS or??),which is a bad idea for a variety of reasons.

I'm not saying user's have a choice. I'm saying this is a decision to be made during requirements or design phase.

> What this proposal describes is a language that is very different from Go. 

If the language chosen is GO, then it's not different. It could be a brand new minimal language that is similar to GO. This is a decision to be discussed.

> It's even more unlikely that that language would be one as powerful 

Why would you want a powerful language at compile time. You're not reading files, using goroutines or most other functionality used at run time.

> It looks like what you want is something like constexpr in C++.  

Constexpr is useless for solving complex problems at compile time (e.g. gettext). It's amazing how a poorly designed feature get's abused because the language does not meet our needs.

> the args can't be evaluated at compile time

At compile time, everything is a constant. The compiler breaks down #xxx( yyy ) as constants into AST's. When #xxx is called, the AST's are made available to the function as ARGS. 

> I used make and awk programs that generate assembly code tuned 
> to the exact demands of command line make configuration. Then it builds in go, then runs.  

I want consistency for everyone, available with GO and easy to use. I'm sure this worked for you but compile time does not need to be complex. Simplicity is your friend.

Thanks, Jon.

Axel Wagner

unread,
Mar 13, 2020, 4:36:56 AM3/13/20
to Jon Perryman, golang-nuts
On Fri, Mar 13, 2020 at 5:48 AM Jon Perryman <jon.pe...@gmail.com> wrote:
This comment is from the proposal. Not one person has disagreed with "very powerful". If you disagree, please say why? How is this not far more powerful than GO GENERATE, pre-processors and macro's?

No one is disagreeing with that, because it is self-evidently true.

But a) talking about the Pros is not how you make a decision. Weighing the Pros and Cons is. And b) even then, "powerful" and "good" are not synonyms. In fact, its powers are specifically why I *don't* like the proposal. Having turing-complete meta-programming means, that it is impossible to trust compilation. It means that any package in the transitive dependency tree can *arbitrarily* extend compile-times. It means you have no assurance that the compilation process is deterministic. It means you have no way to predict what code is actually compiling to.

"It's powerful" is *both* on the Pros *and* the Cons list of the decision process. And decisions are made, by weighing both sides of that list.

Why isn't a very powerful feature important to everyone? Shouldn't the compiler developers spend more than 5 minutes consideration on very powerful features before they dismiss them? Isn't this proposal worth a "like" just to consider if it's possible?

FTR, to you it might feel like only 5 minutes. But that's because you only perceive the discussion about your specific proposal.
The people on the Go team and even just a random person like me have spend *far* more than 5 minutes considering all sorts of ideas for meta-programming. Why do you think `go generate` exists? It didn't used to. It's because the idea of meta-programming was discussed, at length, repeatedly, and the approach of `go generate` was decided on as the best tradeoff.

This proposal is failing because of fear that we will repeat the mistakes of the past. Great developer's will ask how a powerful feature can be made safe in their product instead of finding excuses not to consider it. "liking" a proposal doesn't mean it will be implemented. Instead, it tells developer's  it's important to you and try to find a way to implement that feature.

I believe it is just as self-evident that it is *impossible* to implement this "safely", as it is self-evident that it would be powerful.
And demanding people to spend time on ideas they have already considered thoroughly and rejected, is a denial-of-service attack.
 
Compile time is not affected if #xxx( xxx ) is not used in the code.

But they are, if it is. And I have little to no control over if my dependencies *do* use it.
"If no one uses this feature it has no downsides" is not an argument against the downsides. It's an argument against the feature.
 
Does GO GENERATE or pre-processors save compile time by reading the source twice?

I don't understand what source is read twice, in your opinion. But in fact, yes, `go generate` saves compile time. Because it is not called during compilation. It means you can call `go build` without worrying that you are executing arbitrary code.
 
Are they able to produce results as a programmable GO?

Indeed, yes they can.

do not follow the simplicity and design goals of Go

Why  is this impossible to be part of the requirements?

Choose a compile time language. Possibly GO, Python, Java, NodeJS or??),which is a bad idea for a variety of reasons.

I'm not saying user's have a choice. I'm saying this is a decision to be made during requirements or design phase.

> What this proposal describes is a language that is very different from Go. 

If the language chosen is GO, then it's not different. It could be a brand new minimal language that is similar to GO. This is a decision to be discussed.

> It's even more unlikely that that language would be one as powerful 

Why would you want a powerful language at compile time. You're not reading files, using goroutines or most other functionality used at run time.

> It looks like what you want is something like constexpr in C++.  

Constexpr is useless for solving complex problems at compile time (e.g. gettext). It's amazing how a poorly designed feature get's abused because the language does not meet our needs.

> the args can't be evaluated at compile time

At compile time, everything is a constant. The compiler breaks down #xxx( yyy ) as constants into AST's. When #xxx is called, the AST's are made available to the function as ARGS. 

> I used make and awk programs that generate assembly code tuned 
> to the exact demands of command line make configuration. Then it builds in go, then runs.  

I want consistency for everyone, available with GO and easy to use. I'm sure this worked for you but compile time does not need to be complex. Simplicity is your friend.

Thanks, Jon.

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