
Gomacro: Interactive Go interpreter and debugger with generics and macros - ingve
https://github.com/cosmos72/gomacro#gomacro---interactive-go-interpreter-and-debugger-with-generics-and-macros
======
apatheticonion
C++ style templates...? What's wrong with ripping TypeScript's generic
implementation? It's simple, clean and direct

    
    
        function firstOf<T>(anArray: T[]): T {
             return anArray[0]
        }
    
        interface thing<T, Y> {
            key: T
            anotherOne: Y
        }
    
        const things: thing<string, string> = [
            { key: 'hello', anotherOne: 'world'},
            { key: 'value', anotherOne: 'thing'}
        ]
    
        const result = firstOf<thing>(things)

~~~
htfy96
Typescript, as I know, uses type erasure to implement generics, which can
cause significant overhead in cases like JSON decoder.

------
kouteiheika
> Also, Go is currently lacking generics (read: C++-like templates) because of
> the rationale "we do not yet know how to do them right, and once you do them
> wrong everybody is stuck with them"

To be honest C++-like templates are probably _the_ worst way to do generics.
C++ "did them wrong" by picking C++-like templates and now everybody in the
C++ community is paying the price being stuck with horrible unreadable error
messages, abysmal compile times, an explosion of complexity (SFINAE, CRTP,
metaprogramming using templates, template specialization, etc.) and a myriad
of other problems.

I sincerely hope Go doesn't adopt C++-like templates. Fortunately C++-like
templates are not the only game in town, and there are other, a lot more saner
and principled flavours of parametric polymorphism out there.

~~~
munificent
_> To be honest C++-like templates are probably the worst way to do generics._

I don't think this is fair. Any approach to parametric types has to make some
very hard trade-offs. C++ sacrificed:

* Fast, modular compilation

* Straightforward error messages

* Low cognitive overhead

In return:

* Templates perform as fast as hand-instantiated types. This is something some other languages like Java definitely cannot claim and is a key requirement for C++.

* Template functions can have complex constraints on their template parameters. Deferring type checking until after instantiation means you can do all sorts of interesting things with the template parameter and as long as all of those operations happen to work with the instantiated type, it's allowed. Most other languages place much more stringent restrictions on the expressiveness of generics. For example, in Java, you can't do "new T()". In C#, you can, but you can't do "new T(...)" with any kind of argument list.

Those are both really valuable features, especially in a language where
performance is so critical.

~~~
weberc2
Rust's generics don't have overhead and the error messages are at least as
sane as Java's. I think the problem is with how C++ implemented its templates.

~~~
burntsushi
C++'s templates are more expressive than Rust's generics. Rust is adding stuff
to try to catch up (specialization, const generics). You might see the extra
power as an anti-feature, and that's fine, but it's undeniably useful to lots
of folks and is undeniably a trade off.

~~~
saghm
I feel like part of the reason that I don't run into issues with Rust having
less expressive generics than C++ is that Rust has a ton of other useful meta-
programming features; a lot of the crazy things I've seen solved by C++
templates can be solved in Rust via things like proc macros.

~~~
htfy96
Just wondering if it's possible to implement something like expression
template used in Eigen3 in Rust. C++'s template can be used in more than
generics.

------
enahs-sf
I knew this day would come. While this is a great start into the realm of
Generics, to me, it just doesn't have that easily grok-able feeling that the
rest of Go has. The syntax is kind of clunky and while I applaud the effort,
I'm sure Rob Pike and Co. have been tooling around with this idea since the
beginning of the language. It'll be great to see what shakes out possibly in
Go 2.

------
duwease
It's really useful to have access to an eval() function when paused in a
debugger. That alone makes this useful -- it'd be great to have IDE's like
Goland take advantage of this to provide this functionality.

~~~
GregMartinez
Goland's debugger can evaluate expressions when paused.

[https://www.jetbrains.com/help/go/debugging-
code.html#924cf9...](https://www.jetbrains.com/help/go/debugging-
code.html#924cf9d3)

~~~
duwease
It must be some subset of expressions (or I must have set mine up wrong),
because anything that calls a function (vs a simple conditional statement)
appears to throw an error for me indicating that it cannot execute.

------
Barraketh
Some people that are complaining about C++ templates (and suggesting generics
from other languages as alternatives) are missing the _code generation_ aspect
of templates.

Generics operate entirely at the Type level. For instance (using java)

    
    
      List<Integer> list = new ArrayList<Integer>();
      list.add(1);
      Integer i = list.get(0);
    

is under the hood equivalent to

    
    
      List<Object> list = new ArrayList<Object>();
      list.add(new Integer(1));
      Integer i = (Integer)list.get(0);
    

The differences between the two snippets are entirely at the type level - they
compile to the exact same bytecode. Templates are strictly more powerful -
they allow you to generate different code for each instantiation. The most
obvious place where this is useful is when dealing with primitives that take
up different sizes in memory. This is why you can't use generics in Java with
primitives - you need Objects, because pointers to objects are always the same
size. But if you want performance, so you want to be able to represent
collections of primitives generically, then you need the power of templates
because you need your code to compile to different things depending on the
template parameters.

~~~
aphexairlines
Generics don't have to be implemented with type erasure at the bytecode level.
The CLR doesn't, for example.

[http://www.jprl.com/Blog/archive/development/2007/Aug-31.htm...](http://www.jprl.com/Blog/archive/development/2007/Aug-31.html#jcs-
cs-implementation)

------
jadbox
Very neat project! Not sure what I'd use this for in practice, but it's a nice
proof of concept for several things.

~~~
elcapitan
Definitely nice for learners to have an interpreter!

------
ansible
Bravo!

In my quick read, it wasn't clear if it would be possible to open a channel in
regular Go code, and pass that into the interpreted side.

Just being able to call functions in normal compiled Go code would be enough I
suppose, but direct support for cross-domain channels would be cool.

------
Insanity
Imo, the generics are a downside, not a selling point.

------
whateveracct
Can I use this to interact with my Go projects' source code? I've tried other
Go REPLs in the past and they didn't play nice with my setup (didn't like my
symlinked GOPATH.) So I use a self-hosted playground during development
sometimes.

------
neop1x
stop infecting the clean simple language with that complicated and confusing
mess. Go program in C++ or Rust, please. If someone needs to generate
something, they can use Go generate tools or simple old m4.

------
OriginalPenguin
Why the MPL license? Have you thought about releasing under the same license
as Go instead/in addition?

------
crimsonalucard
Any time you see something like this. Similar to typescript or es6 transpilers
it's a signal something with the original language is off.

Perhaps it's the lack of Generics in golang.

~~~
jimmy1
You are so right -- thats why in better languages like C# and Java you need an
IDE to write half your code for you, and a multi-million line optimizing
runtime to make it run fast.

~~~
meddlepal
Comparing apples and oranges. Java and C# are verbose because of libraries and
frameworks in the ecosystem not because the languages are inherently flawed.

Not sure what your point about the runtimes is? We shouldn't use or build
highly optimized runtimes? Go's original runtime sucked and there's been a lot
of work put into making it better too, I guess they should have just stuck
with it?

~~~
bogomipz
>"Go's original runtime sucked and there's been a lot of work put into making
it better too, I guess they should have just stuck with it?"

Could you elaborate on what the shortcomings of the original runtime were?
Might you have any link regarding this? Thanks.

~~~
jerf
The original runtime had far, far worse GC pauses. They concentrated on making
sure they could make a good one later rather than getting a perfect one out
the door immediately. There was also a series of crashing bugs of varying
severity in the first couple of versions. Even then you had to go a bit out of
your way to find one, but they're a lot harder to come by now.

Nothing that surprising, really.

If you look at Go's release note history:
[https://golang.org/doc/devel/release.html](https://golang.org/doc/devel/release.html)
look towards the first few releases for the bugs they mention. For instance,
here's a 1.1 fix:
[https://github.com/golang/go/commit/d72c550f1c7e13c323f4507b...](https://github.com/golang/go/commit/d72c550f1c7e13c323f4507b57d741ed00f0b0cd)

One of the advantages of not mutating the language too much is that there
aren't very many things like this in the last few releases. I would expect the
first 2.0 release to have a few rough edges even in the first non-beta
release.

