The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type.
However all this can be represented fully without parentheses — and this is possible with Guile using a reader extension without losing any of its power. This is realized, for example, in wisp — a language frontend for Guile: http://www.draketo.de/english/wisp
It’s a full Scheme, but without the parentheses (behind the scenes it simply infers the parentheses, adds them and hands the result to the regular Scheme frontend in Guile).
In short: I think this question is justified. But there are many people who start preferring parentheses when they get over the initial readability barrier.
> The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type.
I've heard this repeatedly over the years, but the explanation unfortunately always stops right there. Could you please give an example of why you'd want to change your source code programatically? It's always assumed that the reader implicitly knows why this is a good and important thing. Perhaps a practical example showing
(A) how this would work,
(B) what the benefit is, and
(C) how the added work in reasoning is worth that benefit.
Note: I personally like the parentheses, as they group everything together so simply.
[Common Lisp's] DOLIST is similar to Perl's foreach or Python's for. Java added a similar kind of loop construct with the "enhanced" for loop in Java 1.5, as part of JSR-201.
Notice what a difference macros make. A Lisp programmer who notices a common pattern in their code can write a macro to give themselves a source-level abstraction of that pattern.
A Java programmer who notices the same pattern has to convince Sun that this particular abstraction is worth adding to the language. Then Sun has to publish a JSR and convene an industry-wide "expert group" to hash everything out. That process--according to Sun--takes an average of 18 months. After that, the compiler writers all have to go upgrade their compilers to support the new feature. And even once the Java programmer's favorite compiler supports the new version of Java, they probably still can't use the new feature until they're allowed to break source compatibility with older versions of Java.
So an annoyance that Common Lisp programmers can resolve for themselves within five minutes plagues Java programmers for years.
>Could you please give an example of why you'd want to change your source code programatically?
To create new syntax and be your own language designer. This is what macro systems allow for. Here's a very contrived and simple example. Guile comes with no equivalent of the `++` operator that we know from C, C++, etc. So in the event that we have some imperative code that is mutating a counter, we'd have to write something like this:
(define counter 0)
;; do some stuff...
(set! counter (+ counter 1))
Quite a lot more typing! It would be especially annoying if we had many such counters. Normally, when we want to factorize code, we'd write a function, but there's a problem: We can't write a function that mutates any given variable. So, this wouldn't work:
(define (++ n) (set! n (+ n 1)))
(define counter 0)
(++ counter)
This is just mutating a local variable `n`, nothing happens to the variable `counter`, it's still 0. So what do we do? Instead of a function abstraction, we'll use a syntactic abstraction instead. Here is a macro that does what we want:
(define-syntax-rule (++ var) (set! var (+ var 1)))
(define counter-a 0)
(define counter-b 0)
(++ counter-a)
(++ counter-b)
(++ counter-a)
Now `counter-a` is 2 and `counter-b` is 1. The `++` macro is a program that writes programs. It takes `(++ counter-a)` and expands it into the code `(set! counter-a (+ counter-a 1))`.
The reason these syntactic abstractions are so easy to make is because of the homoiconic Lisp syntax. I hope this has made sense and is helpful. Moving on from this simple example, we can create entirely new languages that are embedded in Scheme if we wanted to, adding things that are too specific to a problem domain to ever be in the standard language's syntax but very useful for the problem we are trying to solve.
> I've heard this repeatedly over the years, but the explanation unfortunately always stops right there.
Lisp macros are something like C macros, chainsaws, hydrochloric acid, or anything else that's powerful-but-dangerous. This is to say that sometimes they are the one tool you have to use, but often they are unnecessary and should be avoided.
Put succinctly, the problem I write about in the blog post is that macros are essentially always inlined into the output of the compiler. This has the effect of more tightly coupling the modules together than is evident in the surface syntax. (Note that macro invocation sites are syntactically indistinguishable from function invocation sites, which makes this problem worse.)
The upshot of this is what you'd expect: the extent of the logic encoded in macros should be minimized, with the macros translating the code pretty much straight away into something built on more functional abstractions.
This is not to say that Macros aren't useful... sometimes you _have_ to use them to achieve a goal. Just that they probably aren't as big a deal as might be expected given the amount of 'press' they get.
All computer code is a dangerous tool that is often unnecessary and should be avoided if possible. A macro is no more or less dangerous than a function, class, variable, module, or anything else.
C macros have the issue that even when everyone involved in the creation and use of a C macro understands its pifalls, those pitfalls cannot be removed from the macro.
For instance, a certain C macro might evaluate some expression twice. Everyone knows that this is dangerous, but there isn't any way to fix it. They just document it.
ISO C itself says that getc may evaluate its argument multiple times; thus don't do things like getc(stream_array[i++]) unless you remove the macro definition wth #undef.
Lisp macros do not have issues that are unfixable in this way.
Sometimes they have issues that are difficult, though not impossible. Usually that occurs when, to be perfect, the macro would have to do a full-blown code walk. Macros are written that do code walks (for instance the iterate macro).
> Put succinctly, the problem I write about in the blog post is that macros are essentially always inlined into the output of the compiler. This has the effect of more tightly coupling the modules together than is evident in the surface syntax. (Note that macro invocation sites are syntactically indistinguishable from function invocation sites, which makes this problem worse.)
Before you apply macros, you need a well-designed (and documented, and versioned!) API against which the macros will write the code. If all you care about is what the macro syntax looks like and don't put any design into how the expansion works (beyond just massaging it so that it somehow works), then you may run into problems.
Macros don't introduce any problems that writing the same code by hand against the same API's wouldn't introduce.
If someone has to write the code, I don't see how you can get around it: it's either going to be a human, or a macro.
> a certain C macro might evaluate some expression twice. Everyone knows that this is dangerous...ISO C itself says that getc may evaluate its argument multiple times; ... Lisp macros do not have issues that are unfixable in this way.
If your macros is 'fixed' to emulate function call semantics by evaluating its arguments only once, then maybe a function is a more appropriate abstraction in the first place. The whole point of macros is that they let you break the rules of function call application in hopefully useful and predictable ways.
Another way to look at it is that repeatedly evaluating an argument is what you do NOT want for a macro like 'getc', but probably what you DO want for a macro like 'repeat'. The danger lies in the fact that it's hard to tell the difference when looking at a call site in isolation.
Whether or not that danger is an acceptable risk is, of course, situation dependent.
By the way, some 18 years ago, I came up with a system for catching the use of expressions with side effects in C macros. Basically, I introduced an API that you could use in your macro definitions to identify insertions of expressions which would cause problems if containing side effects. This API, at run-time, would parse the expressions, analyze them for side effects, and diagnose problems. (It would also cache the results for faster execution of the same macro site.)
All the programmer has to do is achieve run-time coverage to catch all the problems.
We could define a getc-like macro such that getc(*stream++) would diagnose, provided that the line is executed.
There are all kinds of macros that have to evaluate an expression exactly once, and cannot be made into functions.
;; cond evaluated exactly once;
;; then or else at most once, not before cond.
(if cond then else)
getc doesn't have to be a macro. It illustrates just the point that the macro issues in C are so unfixable that broken macros have even been codified in ISO C.
This brings my back to my original point: "the extent of the logic encoded in macros should be minimized, with the macros translating the code pretty much straight away into something built on more functional abstractions.".
Works in C too, although not as nicely:
void dscwritef_impl(const _TCHAR * format_str, ...);
#define pdscwritef(flag, args) \
do { if (DEBUG_FLAG(flag)) dscwritef_impl args; } while(0);
The funny thing is, I think we're largely in agreement.
I do not agree that an if macro stands for some specific lambda-based utterance. That isn't historically true, or in any other sense. The macro potentially stands for any and every possible way in which its semantics can be achieved.
> I do not agree that an if macro stands for some specific lambda-based utterance. That isn't historically true, or in any other sense.
Huh? Are you saying the use of lambdas does NOT give if* the ability to control the execution of 'then' and 'else'?
My point is that if you're concerned about how often you evaluate a block of code (0, 1, or n times), there are ways to achieve this goal that do not require macros. (And consequently, the macros mainly serve as they should: to clean up the syntax, if necessary.)
I never wrote that macros are required to control evaluation. Rather, what I wrote is that there are examples of macros for which evaluation is specified. In fact, most ANSI Lisp macros are like this; unless stated otherwise, those constituents of a macro call which are forms are evaluated once, and left to right. The whole point is that this sort thing can be specified, because there is a robust way to write macros to meet the specification.
I gave if as an example; it was not intended to be an example of a macro which has to go out of its way to ensure once-only evaluation.
There are common examples of macros that use machine-generated unique variables to hold the results of evaluating an argument form, in order to be able to insert that value into multiple places in the generated code. An implementation of with-slots likely has to, for instance.
In documenting a library of C macros, we cannot specify a strict evaluation order without seriously constraining which of those macros are actually implementable.
> I never wrote that macros are required to control evaluation.
I think that came from me. My point was mainly that 1) control over evaluation is a significant reason to use macros 2) there are other ways to achieve that goal and 3) those other ways should be used to the extent possible. To me at least, this diminishes the value of one of the key headline features of the Lisp family of languages.
Note that this does not mean that I don't want to use the language.'I've maintained a personal and professional interest in the language that dates back over 25 years. When I have the choice, I usually reach for Lisp (really Clojure these days) as the most effective way to write the software I have the time and interest to write. It's just that the reasons for this don't center around the idea of compile time code transformation. (As useful as that can be when needed.)
> There are common examples of macros that use machine-generated unique variables to hold the results of evaluating an argument form, in order to be able to insert that value into multiple places in the generated code. An implementation of with-slots likely has to, for instance.
I do know this, because I've written at least a few of them myself.
> ... insert that value into multiple places in the generated code.
Is that really what you meant to say? You're using a machine generated variable in a macro to 'insert a _value_ into multiple places in the generated code'? (As in, the value itself gets emitted in the generated code?)
The code I link to above does something slightly different. What it does is generate code that uses a machine generated variable to hold the result of a single execution of an expression. It then inserts references to that machine generated unique variable in multiple places in the generated code.
Macros don't "change source code". That is a serious, but common misconception: that they are somehow self-modifying code.
Lisp macros give meaning to syntax that doesn't previously have meaning. In this regard, they are the same as functions.
(foo (boonly) blarg) doesn't have any meaning because foo hasn't been defined.
We can fix that by writing a function foo. Then (boonly) and blarg have to be valid expressions and we are good.
Or we can make it mean something can by writing a macro foo. The macro foo is a function that will operate on the entire form (foo (boonly) blarg) and calculate a replacement for it. The Lisp form expander (a feature of the compiler or interpreter) will call the macro and accept its return value as the replacement for the macro call. Then, the replacement is scanned for more macros; the entire process removes all macros until all that is left is special operators and functions.
A practical example of a macro is the ANSI Common Lisp standard macro called loop which provides a syntax for iterating variables, stepping through collections, and taking various actions or gathering results:
(loop for bit in '(0 3 7 13)
for mask = (ash 1 bit)
summing mask) -> 8329
This entire looping mini-language is implemented in the loop macro. When you call (loop ... args) the macro takes over, analyzes the phrases and compiles them into other syntax.
The natural script writing syntax¹ is an example: The `Enter` Macro defines macros which use their arguments as data (no need to quote anything), but execute any part prefixed with a comma as actual code.
(Enter (Arne))
(Arne (Hello!)
(Who are you?))
The above is actual code which makes Arne say two lines of text.
Essentially the Enter defines a new specialized control structure which is optimized for the task of defining lines of text for a character in an RPG to say.
This removes cognitive overhead while writing a scene: You only write what which character should say.
Essentially you invest into creating a better-fitting tool to simplify all following work. With Scheme you can take this further than with anything else — short of taking over the whole language implementation (which for example Facebook did with their new PHP implementations. With Guile you can take the path Facebook took, without first needing to be a multi-billion-dollar company). But as any other power, use this with care: You won’t want to make your code so much different from what other Schemers do that others have a hard time joining in.
Being able to create code with code, allows you to do away with boilerplate code. E.g. if you got a lot of code with just minor differences, you can make those differences into parameters in a macro which makes each of these code chunks.
That can be utilized both at high level and low level. GOAL is a cool example: https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp. Basically you can express assembly code in LISP syntax and then you can create higher level constructs like if, while, for etc statements as macros composing these lower lever assembly instructions. Because data and code is the same in LISP that allowed Naughty Dog when they used GOAL on the Playstation 2, to swap chunks of code in and out of memory as needed easily to maintain larger levels than the competition. It is also something that allows you to change a running system. I believe there was a case of a malfunctioning satellite running LISP code, which was debugged and fixed while it was running. Shutting it down for fixing was not an option.
I would also add another benefit of only using parenthesis. It makes it really easy to make powerful tools for LISP. Have a look at s-expression based editing. Instead of working line by line, or word by word as we are used to with editors, these work with whole blocks of code at the time. Normal editor commands involve jumping word by word or line by line. with LISP editors you can view the code as a tree with keyboard commands for jumping between tree siblings, up to a parent or down to a child. Instead of selecting x number of lines or words, you can select a whole subtree and delete it, move it, duplicate it or whatever. I think they usually call it paredit. Here is an animated demonstration of how it works: http://danmidwood.com/content/2014/11/21/animated-paredit.ht...
Disclaimer: I never really got used to LISP myself. I think it is cool, but it was too big of a jump for me when I started from C++ background. However I feel more used to it now as I've programmed a lot in Julia which is LISP like but with more normal syntax. Also when I first checked out LISP I didn't understand the need to change the way you think about navigating and editing code. If you edit the way you edit normal code I think it easily gets confusing. You lose track of the parenthesis. I didn't know about stuff like paredit then.
The syntax is mininal, here it is: (functionOrMacroOrSpecialForm arg1 arg2 ...)
That's the whole syntax. So now you know how to program in LISP.
There's no statements in lisp, only the above expression repeated, which you can nest one in another, or sequence them one after another. They're called S-expressions.
For me, that simplicity is the first advantage. It's just very consistent and quick to learn. It also allows to embed everything together, like assign a value in an if condition.
The second big advantage, is that this syntax is very easily parsed into a list and can be easily changed programatically. Lisp lets you do that by defining macros.
A) It works by defining a function which takes the parsed code as an AST, and returns a modified AST. To transform the AST you have the full power of LISP availaible and some convenient operators that make it easier.
B) There's many benefits. Conceptually, it lets you change the evaluation order of code. Normally a function evaluates its arguments from left to right and then passes the resulting values to be evaluated by the function. 99% of the time this is what you want. But what if you want to short-circuit the evaluation of the arguments when one of them evaluates to say false. This would come in handy if writing the AND function. A macro allows you to do it. In other languages, you're given special operators for this kind of thing, but they're limited and you can not add new ones.
Another practical case is aspect oriented programming. Imagine you want to print the argument to all functions and all their return values. With a macro you can do this:
Print steps is able to inject a print statement at multiple code points, around each arguments and around every functions. Without a macro, you would have had to re-write all this manually, and then delete it again once you're done debugging. Some languages like Java give you a complicated framework which can do this to a certain extent, but aspect-J is a pre-processor, just like macros, it's just that the Java syntax makes this really complicated to implement, so you need a framework to do most of the work, or it's not practical.
C) That's up to you to decide. You don't ever have to write a single macro, and should only use them when they are needed and make sense. Now reading code with macros is trickier, because every macro could be a custom operator you have never seen before, or an aspect that does things you're not sure about. To me, this just becomes a thing of don't write crappy unreadable code. Which is true in all languages. I'd suggest teams standardize their macros, and document them well, so new members can quickly get familiar with your team's macros. Once familiar with a set of macros though, they make you a lot more productive and do make code more concise and even easier the read sometimes.
One big advantage is that this unified recursive representation of code allows structural editing. With things like Emacs's paredit you manipulate code structure directly by splitting, joining, and moving subexpressions instead of editing code as flat lines of characters.
Btw, of modern Lisp dialects, I do not like Clojure for undermining this advantage by not syntactically grouping everything that is grouped semantically (e.g. binding pairs in let) just to use less parentheses. In my opinion, Scheme syntax (Guile is a Scheme implementation) is much better.
I think that's a good point, not sure why Clojuse did that. I get confused because some macro expect grouping, others don't. I think it happened as an accident, different people wrote the different core macros and decided on slightly different parsing rules.
Many programming languages use braces, parentheses and brackets to convey structure.
Javascript and C do it this way:
if (foo) {
bar(42, zonk());
}
Guile/Clojure/etc do it this way:
(if foo
(bar 42 (zonk)))
If you didn't have the separators, programs would
be harder to interpret for compilers and human readers, as it's harder to tell what the programmer meant from
just
It's a LISP dialect. Brackets are essential to tell the difference between arguments and function calls... take for example in C: foo(bar(1)) would in lisp be (foo (bar 1)).
If it were to just be "foo bar 1", you couldn't tell the difference between (C style again for clarity): foo(bar(1)) and foo(bar, 1).
Some newer functional languages have a composition operator which allows you to write this without the brackets, but the brackets still are easier to follow in many cases.
This "problem" is not unique to Lisps. Quite often, when I look at a piece of code written in C++, especially when it uses lambda functions inside calls, I can't help asking myself why there are so many brackets (and whether a Lisp would be a better alternative to C++, syntax-wise).
The syntax of the lambda itself in C++ is sort of funny: it requires to use all the bracket types at the same time!
But they're not interchangeable, so they give an person reading the code a strong hint whether it's a array index, function call/grouping, or a code block.
Oh, that's yet another issue: in the context of the above example (which, incidentally, was not merely a list of all kinds of brackets) the meaning of the pair of square brackets is changed from 'array index' to 'lambda'.
It is a Lisp thing. If you have an editor like emacs with Scheme support, it is possible to format in a way that makes it quite easy to read: in fact, the formatting reveals the AST.
Not strictly true... there is still parsing involved in reading Lisp data structures from a character stream. (It's just much less involved than in traditional infix languages.)
The way to think of it is this:
1) Lisp has a much more comprehensive (and read/write) syntax for its core data structures.
2) Lisp, the language, is defined in terms of those data structures rather than in terms of character sequences and grammar productions.
I can see that, but it doesn't feel quite right. The tree you get directly from deserialized source text is still a bit more fine grained than I'd expect a true AST to be.
To see what I mean, consider this:
(if condition 1 2 3)
This expression can be deserialized into a Lisp data structure, but it still contains a syntax error, and I don't think a true AST would be able to represent that syntax error.
Lisps take a couple months of programming in for it to start being easy to read if you're coming from only c-style languages, but it works out well in the long run. Sure makes refactoring a breeze.
C is part of the Algol family. Fortran was/is syntactically and semantically quite different. Algol was almost contemporaneous with Fortran and, although did learn from Fortran, was, at least partly, a reaction to its perceived flaws.
Well, contemporary Fortran is probably part of Algol family too, since newer versions of Fortran (at least 77 onwards) incorporate the block structured programming concepts from Algol.
The "family tree" analogy works imperfectly for programming languages since it is more of a directed cyclic graph than a tree structure – Fortran influenced Algol and then Algol in turn influenced Fortran.
I'm an Indian and can verify that. A lot of scumbags keep winning and hold onto power here usually by hook or crook. In fact even the prime Minister modi was on a mass murdering case of Gujarat 2002. He was the chief minister when the riots Happened!! That guy has still not even apologized or said sorry to the families whose people were killed. The current govt has the largest share of criminals in power. There are some honest players coming up. We'll see if they are really honest in a few years.
They are not the prime ministers now. The context that we are talking here is about the current govt. If the previous govts had lots of wrong doers then it doesnt mean the current govt doing the same is okay. Get your priorities straight.
Using the same argument - we shouldn't discredit those crimes and criminals just because they are not prime ministers or chief ministers now. Get your priorities right.
I dont know why such scumbags expect an apology from Modi. Supreme Court gave him clean chit. I am from Ahmedabad and whenever I see the reference of 2002 riots, I know its from ignorant people outside of Gujarat and who doesnt know anything about Godhara incident. He did what he could as a CM, only outsiders (non-gujjus) still find he is the one should be blamed. What a pitty!
1. https://en.wikipedia.org/wiki/Godhra_train_burning
> The current govt has the largest share of criminals in power
Surely you jest? No mention of Congress who have literally destroyed our country by their rampant corruption and being in power for so long that it is proving to be a gargantuan task to get back on our feet?
Yeah the congress has to be gone for good. Also the current govt! They have the highest no of criminals in the parliament now. Its not even up for debate. They need to be weeded out.
> In fact even the prime Minister modi was on a mass murdering case of Gujarat 2002. He was the chief minister when the riots Happened!! That guy has still not even apologized or said sorry to the families whose people were killed.
I think you should stop whatever you are doing and get appointed as a judge in the Supreme Court of India. Obviously you know so much more than what they know or have deduced about criminals in India, much less the PM.
The commenter is deluded and does not care for facts. This case has been running in prime coverage for the last 10-12 years because almost everybody took an interest in it, because they wanted to "Get Modi". Many inquiries were setup, including special task forces, commissions, many US & European based NGO's in the guise of missionaries came to India searching for mass graves, he was banned from getting a Visa to enter the US, the supreme court in India held multiple hearings etc. After all that, he was deemed innocent. This shows that there is plausible evidence that the commenter was not serious, & in fact a troll or he was absolutely clueless, yet does not & cannot resist from accusing someone of being a "mass murderer". So there, that's the joke! You can't get more serious than that about this situation.
Thank you for providing the context that is helpful.
However a quick skim of content seems to suggest that a significant amount of people do not have confidence in the impartiality of the investigations, and that it remains a controversial issue.
>a significant amount of people do not have confidence in the impartiality of the investigations
Generally, you would be right in assuming that. But in this case, Modi was in quite a vulnerable situation, when the primary opposition party (Congress) was in power in the central government at that time; they even had CBI (Central Bureau of Investigation) in their control, there were too many international parties out to dig up evidence and accuse him (which they did, sans evidence). But at the end, not one charge stood up. In other words, he was proven innocent multiple times against all odds. The Visa ban was also overturned without a whimper, in fact Modi & Obama became such good friends....
did you not read the word 'was' ? Im not saying he is a mass murderer. Im only saying he was on the case for long. Your insecurity about this only makes me even more suspicious.
If he said "Sorry" the scumbags would say "See, he said 'Sorry', obviously he's guilty", if he does not say "Sorry", the remaining scumbags say "He did not even say 'Sorry', he needs to take responsibility"!
If you think people can't see through such antics as you're playing, you are really deluded & grossly underestimate the general intelligence of humans!
WTF man! Just because people do not agree with you, they become "insecure"? Unless you have been living under a rock or deep inside a cave you should know that almost every political party in India as well as many international NGO's, including our very own Hillary Clinton were out to "Get Modi". There were at least two Special Task Forces (STFs) that said there is no evidence of Modi being involved in the killings. He was the CM at that time, that was his only fault. The Courts in India have given him a clean chit, this was when he was a mere CM, at a time when the Congress party was in power. I mean, you got be really dense...
And what's with the 'was'? Just because you claim someone "was" a mass murderer, you can absolve yourself when every known & serious inquiry against him proves otherwise? Please try to be objective & analytical. Look up facts. Just because you like things to be a certain way does not make it so. Try to understand the divisive politic people play, but their best hands couldn't prove what was false.
I meant it seriously - if anyone can prove that he is guilty, go and make your case. Stop being a keyboard warrior!!
There is a different sense of freedom that I believe the person you replied to is alluding to. The cultural and social norms may be more ingrained in India, but there is a less litigious society that overlooks or ignores small offenses, or may not even have regulations preventing many things that would be illegal in the US from taking place. It's not necessarily desirable freedom, but freedom nonetheless.
Did they even pay lip service to a plan? Even one that they never had any intent to implement, or one so obviously impractical that any rigorous thought would poke holes in?
Of course they did. It was said to remove corruption, stop black money and stop terrorism. Just emotional non sense and fake hopes. It shut a lot of people's mouths as they labelled the opposers as anti national. There was a lot of online abuse to netizens as well. Still is.
They efficiently managed to pull off this massive failure without widespread anger.
Words can do a lot of damage than weapons. Gandhi used it for uniting people into a good cause and this guy uses it for his own fantasies.
I'm glad the veil is coming off though. People are disgruntled that it's just talk and no work.
Really well written. We have a similar story where we re wrote parts of our Java code in go and the build time has reduced from 15m to 3.6m! Coffee break to reading a small medium article.
sure. Never denied. But we are breaking apart that java code part by part. The docker build size is also very small as mentioned in the article. Our app involves lot of bandwidth so we good with smaller containers.
More importantly, how much time did it take to rewrite code that took 15m to compile! Are the machines working for the man, or the man for the machines ;)
As this is the 3rd language in your code base, 1st there was java, then there was Scala and now GO. I do hope all Scala code is gone by now! I assume this decision and investment was extremely well supported, but that is not obvious from your blog post and supporting comments here.
So 12 months of effort -> at Bay area salaries and costings that is in the order of magnitude of 300,000USD. Your parent company had 6.6 million NZD profit last financial year. So for investing around 5% of the total profit of the larger group your mayor benefit is reduced compile times. Plus some other second system benefits.
That is a rather expensive decision to have taken, and I think if you had been forced to do a proper ROI investigation before hand you would not have gotten that. In my experience when doing these calculations and getting the numbers down it is never the financially wise choice to change languages but instead actually fix the pain points that people have with the language and most often the actual project setup. It is only when a language change is incremental, adds a key feature or is a market requirement e.g. for deploying on certain devices that a new language makes financial sense.
I am not judging your GO decision over Scala as a better language but I am judging your management layer for doing this. Especially as it sounds like from other posts that GO is now 1 more language to support in your company. Increasing certain costs outside of yours as a team in cross team training opportunity, support and monitoring etc...
Of course sometimes changing language is like changing from speaking French to Italian in the office and hoping that office politics will disappear... Been there done that, it did not work out as hoped by the developers.
Sorry I was confused between your experience and the opening post which was moving from Scala to GO. So I assumed you were working for Movio and used their numbers. Therefore my post does not make any sense :)
Then it was a Java to GO move. I wonder where your compiles take the most time. For our work building the jar files are the most expensive part. Javac is about 20 seconds all in for about 3000 files to compile on my 2009 macbook.
Im sorry but I find the parent very correct here. The headline is hype based. The README shows no signs of benchmarks or comparisons to define its acclaimed speed. Also mentioning an upcoming feature in the headline is not something people would prefer. Its still okay as its open source and people can do what they want. But to be taken seriously, it needs to be as realistic and true as possible.