Contrived Go comparison?

polaris · · 53 次点击    
<p>While watching this Perl 6 video <a href="https://youtu.be/lpu-3UF_b48">https://youtu.be/lpu-3UF_b48</a> - relevant material starts at 34:53 and takes about 2 minutes - the author compares several languages to Perl 6.</p> <p>I know Go isn&#39;t OOP. I know Go is somewhat verbose. However, you can&#39;t read the code on the video. Is there an experienced gopher who can clarify? Is this example somewhat contrived? Or is Go really that wordy?</p> <hr/>**评论:**<br/><br/>icub3d: <pre><p>Yes, it is contrived. He&#39;s comparing a snippet to an entire poorly written Go program. I don&#39;t think you could get down to the same lines of code as Perl but you could easily half that size. Go is generally considered to be more terse than Java and C++, so the fact this his examples don&#39;t illustrate that suggest he is doing something wrong.</p> <p>The readability and writability of languages are usually a seesaw where improving one hurt the other. Language designers have to try to find a balance. It&#39;s honestly more a matter of your taste and time investment. Languages that are terse usually require more time on your part to get comfortable but can sometimes become more productive.</p> <p>I like Go&#39;s balance and think it suits my style so it&#39;s my language of choice.</p></pre>titpetric: <pre><p>Definitely no need to create a <code>func (*Point) String() string</code>, but seems he did more than just one thing wrong anyway, since SetX and SetY don&#39;t actually set anything. Or how he&#39;s not using them from NewPoint (as he did in Java). I gave a stab at optimizing this tire fire in a comment below :)</p></pre>hobbified: <pre><p>No, they&#39;re the same level of completeness — the definition of the point type, without any code to exercise it. There&#39;s no main in the Go example, it won&#39;t do anything.</p></pre>icub3d: <pre><p>You&#39;re right it&#39;s not an entire program but it is substantially more than what an experienced Go programmer would write. He&#39;s using idiomatic Perl 6 and non-idiomatic Go and trying to make a comparison. That&#39;s almost always biased because few have taken the time to explore both languages properly (let alone the several he lists; I&#39;m sure we could scrutinize most of them in other subreddits).</p> <p>There are several places where his Go is too verbose. Like mentioned above, you wouldn&#39;t need/use a String() method. The default fmt.Print* would give you what you need. You also don&#39;t need to do the IsValid check in the way it&#39;s done there. It would be as simple as:</p> <pre><code>if x &lt; -10 || x &gt; 10 { return errors.New(...) } p.x = x return nil </code></pre></pre>idobai: <pre><blockquote> <p>The readability and writability of languages are usually a seesaw where improving one hurt the other...</p> </blockquote> <p>...if your language designer has no experience with programming besides writing some toy apps in C and Perl...</p></pre>icub3d: <pre><p>Not sure what you mean. That&#39;s almost always true for languages. There is some overlap but often the ability to write in a language quickly means it&#39;s harder for someone to come up to speed.</p> <p>He alludes to this in his presentation. I think his point stands that perl is &#34;expressive&#34; but that almost always means readability suffers. He says it&#39;s not that bad but then he uses his French as an example. What&#39;s he&#39;s alluding to is that &#34;with practice, the perl 6 code will become second nature&#34;. Said another way, perl suffers from readability issues. It take more expertise to be sufficient at reading it.</p></pre>le_frogballs: <pre><blockquote> <p>The readability and writability of languages are usually a seesaw where improving one hurt the other</p> </blockquote> <pre><code>quicksort :: (Ord a) =&gt; [a] -&gt; [a] quicksort [] = [] quicksort (x:xs) = let smallerSorted = quicksort [a | a &lt;- xs, a &lt;= x] biggerSorted = quicksort [a | a &lt;- xs, a &gt; x] in smallerSorted ++ [x] ++ biggerSorted </code></pre> <p>vs</p> <pre><code>func sort(values []int, l int, r int) { if l &gt;= r { return } pivot := values[l] i := l + 1 for j := l; j &lt;= r; j++ { if pivot &gt; values[j] { values[i], values[j] = values[j], values[i] i++ } } values[l], values[i-1] = values[i-1], pivot sort(values, l, i-2) sort(values, i, r) } </code></pre> <p>oh man it so isnt. and this was probably one of the most forgiving-to-go examples i couldve used. No (if err != nil) madness, nothing involving something that would warrant using generics (Go would have to implement the same logic for each type). Any language in 2017 whose rebuttal to not having generics is &#34;use copy paste&#34; and &#34;use code generation&#34; (<a href="https://appliedgo.net/generics/" rel="nofollow">https://appliedgo.net/generics/</a>) is not worth even the faintest attention from any self-respecting developer</p> <p>Its sole reedeming quality appears to be its runtime. In almost everything else its comparable to some random dude proclaiming &#34;look at this!&#34; at a mudhut he built and the world collectively heralding him as Frank Lloyd Wright reincarnate. I just don&#39;t get it </p> <p>EDIT: If you&#39;re going to downvote, I hope you&#39;ll leave at least a few words in a reply with hopefully a valid rebuttal. Or whatever. I guess I&#39;m asking for it to a certain extent with the mudhut analogy which i want to clarify isn&#39;t simply Go bashing: it&#39;s real world compliment argument is that Go appears to simply ignore much of the indispensable knowledge we&#39;ve accumulated on programming language theory over the past half century (and more)...and for what reason? Again i just dont get it. Why sully a good runtime with god awful syntax and language features (or lack there of) from the Bronze Age? Is it out of spite? Was it on purpose? I genuinely want to know. Its almost arrogant in a way. Like the language designers decided, in an almost biblical display of obstinance, to just say &#34;we know better than all of the computer scientists who have <em>established</em> X, Y, and Z are bad ideas for reasons a, b, c&#34;</p></pre>icub3d: <pre><p>Ehh, it seems like your example actually proves my point. I&#39;ve never heard of anyone saying Haskell gets high marks in the readability category of language evaluation. Remember readability isn&#39;t just &#34;does it have generics&#34; or &#34;can I read my own code&#34;. It involves how well another person, especially a novice to the language, could read your code or how long it would take a novice to become an expert in the language.</p> <p>I consider myself a self-respecting developer and I use Go. I&#39;ve mentored a team at work and we&#39;ve designed and built an extremely complex system in just a matter of months. I can&#39;t imagine the same would have been the case if I picked Haskell. I&#39;d still be trying to explain what a monad is. :)</p></pre>Macrobian: <pre><blockquote> <p>It involves how well another person, especially a novice to the language, could read your code or how long it would take a novice to become an expert in the language.</p> </blockquote> <p>What&#39;s wrong with designing languages so that they&#39;re readable by experts?</p> <blockquote> <p>I&#39;ve never heard of anyone saying Haskell gets high marks in the readability category of language evaluation.</p> </blockquote> <p>I dunno, I work with a lot of Scala developers and they think it&#39;s readable. </p></pre>icub3d: <pre><blockquote> <p>What&#39;s wrong with designing languages so that they&#39;re readable by experts?</p> </blockquote> <p>Nothing inherently wrong but when you are doing a real language evaluation it is one of the criteria and it&#39;s important as the team makeup and duration of the project will affect being able to use a language that requires substantial ramp up time where the pay-off is later in learning curve. I&#39;m just trying to point out that there is give and take. No language is perfect and is going to have weaknesses. You have to pick the right one that fits you and your team given all the constraints you have.</p> <blockquote> <p>I dunno, I work with a lot of Scala developers and they think it&#39;s readable.</p> </blockquote> <p>The thing about Go is that it seems to hit a sweet spot for many of the evaluations I do. Yes, your group of Scala devs might do well in Haskell or Erlang, so picking Go may not be in their best interest for some projects. If we are being realistic though, your group is probably a heavily skewed sample set. Most people will be coming from a procedural language like Java or C++. In the evaluations I&#39;ve done, Go gets a B in most categories. Something like Haskell might get an A in a couple categories but an D in others. When you average it out, Go is the best fit.</p> <p>So, yes it doesn&#39;t have generics. My project hasn&#39;t missed it though. We just had to think more like Go. This seems like something that a Haskell programmer would understand. If you try to port your C program directly to Haskell, you&#39;re likely misusing the language. In the same vein, you need to think about how you use Go differently than you would use Perl (my original point; and why I think his example is contrived).</p></pre>le_frogballs: <pre><blockquote> <p>No language is perfect and is going to have weaknesses</p> </blockquote> <p>I dont consider the fact that you can&#39;t immediately sit down and start writing haskell to be a weakness. In fact I believe it&#39;s a strength if anything. I&#39;ve always hated that argument. Why would you want a language to be so trivial so as to allow for anyone to sit down and begin writing it? How much of a colossal stain on the sum total of Go code bases as far as shit code has been produced by people with this mentality? So yes you aren&#39;t able to be immediately productive but like i said how miserable would that code look? </p> <p>Haskell in a way forces you to write at least decent code. One of the reasons for this is that its purely functional (unlike Scala). Every side effect must be performed in the IO monad, literally forcing you to think about side effects, where in other languages you can just perform them willy nilly. Do you know how much shit code is out there because some company hired a bunch of newbs without properly vetting them, then assigned them to some project in say a langauge like go. They immediately started working on it and thought everything was going great &#34;Hey this language is so simple to write&#34; in. Then next thing you know months down the line the whole project has literally turned into a flaming ball of shit. And this is only one scenario.</p> <p>I&#39;m done looking at piss code. I&#39;ve looked at it enough (at work I maintain a pretty substantial Scala service and am in the process of day by day rewriting, so Ive been staring at shitty code pretty much every day for over a year now (and of course I think back to when i first started and I opened said project and I <em>didnt think</em> it was shitty haha) Do you know if there weren&#39;t senior engineers around that they had hired with me how much more i couldve destroyed that project. And this is in Scala, a language with infinitely more abstractions than Go. If it had been writtten in Haskell it wouldve taken me a month before I could even contribute a PR because I, rightfully so, would need to learn what hell i&#39;m doing before just blindly jumping in</p> <blockquote> <p>Go gets a B in most categories. Something like Haskell might get an A in a couple categories but an D in others. When you average it out, Go is the best fit.</p> </blockquote> <p>Lol no Haskell doesnt. Believe me. And if you&#39;re trying to imply that averaged out Go would score higher...believe me it wouldn&#39;t. As I said its runtime is literally its only reedeming quality. Haskell will blow it out of the water in all other respects (Go&#39;s GC is better) </p> <blockquote> <p>We just had to think more like Go</p> </blockquote> <p>Having said what I&#39;ve said what does this even mean? You&#39;re literally trying to pretend like like the lack of abstractions Go gives you is actually somehow clever and requires you to readjust you&#39;re thinking until you agree with the rest of the mob: &#34;Yea this is so much better!&#34;. That&#39;s called brainwashing not readjusting the way you think. You have to actually readjust the way you think with Haskell at first simply because it rests firmly in the functional paradigm and literally doesnt permit you to write imperative code at all (you can simulate it but its still not the same thing at all). So thats what people are referring to as far as the initial learning curve. Once you get sufficiently comfortable with functional programming its pretty simple to expand upon what you&#39;ve learned by just exploring other native features in the language, since you already have a baseline understanding</p> <blockquote> <p>if you try to port your C program directly to Haskell, you&#39;re likely misusing the language</p> </blockquote> <p>I woudn&#39;t. I&#39;d port them to Rust which is where all the hype should be. Not Go</p> <blockquote> <p>you need to think about how you use Go differently than you would use Perl (my original point; and why I think his example is contrived)</p> </blockquote> <p>Lol what ive said is exactly <em>why it isnt</em> contrived. That quicksort is what any quicksort looks like in any vanilla imperative, mutable language without interesting abstractions. That was exactly my point and why I picked it like i said. Its literally the same shit we&#39;ve had for the past half century. And mind you I couldve gone in the deepend and found an example that displays all of Go&#39;s many warts (which aren&#39;t even warts. They&#39;re like bunyuns compared other languages&#39;s warts). But i didnt cause im not here to troll (at least not immediately, when I run out of patience I will probably will). And you could find a bunch of people, who have migrated to functional programming that would agree. In fact I&#39;d be curious to know if theres even anyone who tried functional programming and said &#34;this sucks I&#39;m going back&#34;. Thats where things are moving my friend and its exactly because its an objectively better way to solve almost any given problem. There will be huge potholes along the road like Go but I have faith in the computer science community at large that people can and will evolve</p></pre>Sythe2o0: <pre><p>There&#39;s a lot of condensed syntax in the Haskell example that, yes, makes it hard to read. Anyone can read the Go example. </p> <p>To understand the Haskell example, you need to know that <code>++</code> concatenates things, that function application (if it&#39;s called a function, sorry) doesn&#39;t use parens like almost every other language does, that <code>|</code> defines a new variable from some kind of <code>&lt;-</code> syntax which is I suppose equivalent to <code>pop</code>? And you need to know that when you turn that arrow around it now means function application? And if it&#39;s an equal sign instead its defining what kind of type a function accepts? You also need to know what an <code>Ord</code> is, when 90% of languages would be using <code>int</code> or maybe <code>Sortable</code> or <code>Comparable</code> or something. </p> <p>You also need to know that functions can be defined multiple times with each definition taking in a unique argument pattern. </p> <p>That&#39;s a lot of stuff to know man</p> <p>In comparison, in Go you need to know math, for loops, function calls, and integer comparison operators, all using common syntax. </p></pre>le_frogballs: <pre><blockquote> <p>Anyone can read the Go example.</p> </blockquote> <p>Thats precisely the problem. Any first year CS student can understand it and almost every first year CS student knows fuck all about building software. So imagine the shitstorm that would occur if the 2 came together. That&#39;s exactly why that simply <em>isn&#39;t</em> an advantage or something to tout around as being a plus</p> <blockquote> <p>To understand the Haskell example, you need to know that ++ concatenates things, that function application (if it&#39;s called a function, sorry) doesn&#39;t use parens like almost every other language does, that | defines a new variable from some kind of &lt;- syntax which is I suppose equivalent to pop? And you need to know that when you turn that arrow around it now means function application? And if it&#39;s an equal sign instead its defining what kind of type a function accepts? You also need to know what an Ord is, when 90% of languages would be using int or maybe Sortable or Comparable or something.</p> </blockquote> <p>Read a little bit about Haskell first before you try to disect a program. <code>Ord</code> is a typeclass which is basically a better interface (so no need to pass in a freaking instance like you would in another language with <code>Sortable</code> or <code>Comparable</code> or whatever). All thats saying is &#34;give me a type that implements the Ord typeclass&#34;. Int is one such type. Ord&#39;s members are &gt;=, &lt;=, &lt;, &gt; (among others). You get them for free on whatever type you pass in that meets that contracts. Yes ++ is a function (most thing sin haskell are). No theres no <code>pop</code> cause we aren&#39;t in mutable land so forget about that. thats a guard: [a | a &lt;- xs , a &lt;= x]. all its saying is &#34;give me all the a&#39;s less than x as a list&#34; </p> <blockquote> <p>That&#39;s a lot of stuff to know man It may be man. But you&#39;ll be all the better for it if you take the time to. If you stick with Go youll be writing the same shit you&#39;ve been writing all you&#39;re days as a programmer</p> </blockquote></pre>2fplus1: <pre><p>I wrote mostly Perl from the late 90&#39;s to the early 00&#39;s. The obsession with conciseness has always been there (eg, Perl &#34;golf&#34; competitions). The result is Perl&#39;s reputation as a &#34;write-only&#34; language or &#34;executable line noise&#34;. Not entirely deserved (there is good Perl code out there), but it didn&#39;t come out of a vacuum.</p> <p>Yes, you can pretty much always write a given program in fewer lines of Perl than Go, but I&#39;d pretty much always take the Go program over the equivalent Perl if it&#39;s something that I&#39;m going to have to maintain over time or collaborate on with other developers (not even getting into performance, concurrency, or deployment complexity).</p> <p>(maybe Perl 6 is radically different. I haven&#39;t really looked at it yet. I got tired of hearing about how great it was going to be when Perl 6 came out... back when I was still working in Perl every day).</p></pre>SeerUD: <pre><p>Honestly, it looks a little bit like it is - but even still, Go <em>is</em> quite a verbose language. But that is one of it&#39;s strengths. I took a deep look into these &#34;concise&#34; languages like Scala for example, and I came to the conclusion when I returned to Go (even after initially not liking the verbosity of Go and actually trying to seek out these more concise, modern languages like Scala) that all of that conciseness can come with a great cost.</p> <p>Go is more verbose, but that helps it a few ways; it&#39;s trivial for new developers to pick it up and run with it, it&#39;s easy to read existing code, and other people&#39;s code (and the standard library&#39;s code), and it helps keep the language simpler which makes keeping the tooling top notch great. Scala again is another example of a language where the complexity of the language itself has hurt the tooling a <em>lot</em> (e.g. extremely slow compile times, limited tool support, and limited willingness and ability to actually write new tooling for it).</p></pre>: <pre><p>[removed]</p></pre>: <pre><p>[removed]</p></pre>: <pre><p>[removed]</p></pre>: <pre><p>[removed]</p></pre>: <pre><p>[removed]</p></pre>: <pre><p>[removed]</p></pre>hobbified: <pre><p>The point isn&#39;t <em>conciseness</em> though. It isn&#39;t &#34;OMG my code is shorter, so it&#39;s better&#34;. It&#39;s &#34;look at all the work you need to do to be correct.&#34; </p> <p>If you don&#39;t write this much code, you&#39;re allowing your type to admit invalid values, which will wait until the worst moment to break. If you don&#39;t <em>know</em> that you need to check things this way, too bad, you lose. If you <em>do</em> know, but make a mistake like getting so distracted by enforcing constraints in your setter that you forget to actually set the value (as <a href="https://www.reddit.com/r/golang/comments/75ol0g/contrived_go_comparison/do7u8nx/" rel="nofollow">Ovid actually did</a> in the Go example), then you&#39;re screwed too — you get code that builds, but has bugs. But every line of code that you don&#39;t have to write is a line of code that you don&#39;t get an opportunity to make a mistake in.</p> <p>I hate the Point class, because a terrible example of OO — it has no worthwhile behavior, and objects are supposed to be units of behavior, not bags of data. But in this case, it kind of works, because the point is that you should only be looking at the code that makes a type&#39;s behavior unique, and since our example has basically no unique behavior, it should also have basically no code. An idea like &#34;it has a constructor, that accepts certain params, validates them according to certain rules, and puts them in its own state&#34; should be bedrock. It just means that you work the same as everything else, so there&#39;s no need to draw a reader&#39;s attention to it, and no need to lead the computer step-by-step through the process, opening yourself up to the possibility that you&#39;ll make a mistake.</p></pre>jerf: <pre><p>FWIW, last I knew Perl 6 is still a complete nonstarter for any serious programming project, because their performance is entirely unacceptable. They were, last I knew, another several times slower than Perl 5, which is one of the slower languages around but is fast enough to do real work. I believe it is one of their current focuses but at this point you&#39;re justified to observe that the Perl6 world has a nasty habit of getting to a certain degree of progress and then throwing the entire interpreter away and starting over again; you have to assign a non-trivial probability that they&#39;re going to encounter fundamental performance issues in their current implementation and that getting to decent performance is going to take longer than they are currently claiming.</p> <p>In theory I don&#39;t see any reason why they can&#39;t get up to at least Perl 5 levels of performance, but until then I&#39;m not terribly inclined to listen to them lecture other language communities about how awesome their language is. For all that idobai is poorly representing the Scala community, it at least has been used to do real work at production scales for a while now.</p></pre>titpetric: <pre><p>Edit 2: TL;DR the Go example here is contrived, Go code can be shorter without much effort. Also: the example isn&#39;t functionally equivalent to other examples provided (java, c++,...). Code coverage definitely wasn&#39;t 100% or guy would know that <code>SetX</code> doesn&#39;t actually set anything.</p> <hr/> <p>The example is contrived, and could easily be reduced by 30% with a naive refactor. But I wanted to be explicit, so I tracked down the slides from the comments, and came up with this:</p> <p>This is the starting version:</p> <ul> <li>slides: <a href="https://www.slideshare.net/Ovid/perl-6-for-mere-mortals" rel="nofollow">https://www.slideshare.net/Ovid/perl-6-for-mere-mortals</a> - slide 76 for Go</li> <li>source: <a href="https://play.golang.org/p/1-JDgkIvWl" rel="nofollow">https://play.golang.org/p/1-JDgkIvWl</a> - SLOC 56, not counting main but counting whitespace between functions.</li> </ul> <p>What the author did in <code>java</code> (slide 72) was:</p> <pre><code>public double GetX() { return this.x; } </code></pre> <p>Which is valid syntax in Go too (gofmt doesn&#39;t expand this). And so we come to SLOC 51 (39 without whitespace/imports), <a href="https://play.golang.org/p/kZ3PUw4TLc" rel="nofollow">playground link</a>. Note: I didn&#39;t modify <code>String()</code> or <code>IsValid</code> as well, that&#39;s low hanging fruit for later.</p> <p>Before we continue, I would like to fix the original <code>Set*</code> functions, as they didn&#39;t modify the point value. The java example does. The java example also doesn&#39;t return the previous value, so I&#39;ll keep the same semantics, returning just the error. SLOC stays the same: <a href="https://play.golang.org/p/F7-o6xkq58" rel="nofollow">playground link</a>.</p> <p>The function <code>IsValid</code> can also be reduced to a oneliner (directly return the boolean expression in the if-clause). Reduced to SLOC 48: <a href="https://play.golang.org/p/X1W0N1Zy6j" rel="nofollow">playground link</a>.</p> <p>We can use <code>Set*</code> now from <code>NewPoint</code> which the author didn&#39;t. We can also use named returns, which don&#39;t really modify the output that much, since we could/should still return nil for *Point. Unless we needn&#39;t? Anyway, we are still stuck at SLOC 48 - <a href="https://play.golang.org/p/4Tr6L3O4Z8" rel="nofollow">playground link</a>. Looking at other examples (C++) we can see that they are also structured differently. The returned error comes from the validation <code>constrain()</code> function. And looking at the Java constructor, we could also similarly modify our NewPoint. I mean sure, panicking would be less verbose, but we should handle those errors.</p> <p>Next: I modified SetX to return the original *Point, not adding any SLOC. They now return nil in case of an error. Due to savings in NewPoint, we reduce the code down to SLOC 45. <a href="https://play.golang.org/p/ly9siIA4RQ" rel="nofollow">playground link</a>.</p> <p>This is just about the limit of where you can go without being even more inventive. Cleaned up the low hanging fruit and ended up with 39 lines of code (28 without whitespace/imports) - <a href="https://play.golang.org/p/iBEvv_T3xY" rel="nofollow">playground link</a>.</p> <p><strong>So, the results? -23.5% reduction of lines, -28% reduction not counting whitespace.</strong> The biggest issue in reducing this further is finding a pattern to reuse.</p> <ol> <li><p>Both SetX and SetY have some common code, which is intertwined with <code>isValid</code>. You could reduce each by one line, but need to expand isValid to return the original float value and a declared return error (can&#39;t use bool, can&#39;t use <code>:=</code> short decl because we still need to write to p.x, example here</p> <pre><code>func (p *Point) SetX(x float64) (px *Point, err error) { if p.x, err = p.isValid(x); err != nil { return nil, errors.New(&#34;Point X out of range!&#34;) } return p, nil } </code></pre></li> </ol> <p>Edit: <del>Reddit doesn&#39;t want to format this.</del> Suffice to say, you&#39;d need to declare a new variable, if you want to use a bool value something like <code>p.x, ok := ...</code>, but that would throw an already declared error on p.x; and you don&#39;t have a way to add a bool without adding a line of code as well. If you had several Set* methods, you&#39;ll see some gains tho, but not for just two.</p> <ol> <li>NewPoint imho shows the most acute defect about Go as a language, and it doesn&#39;t have anything to do with generics. There no simple way to chain execution of multiple functions, to set values from an if clause, and break out of the execution flow if any of them may return an error.</li> </ol> <p>Picking some other language, you could do something like this (adapted for go semantics):</p> <pre><code>if ( ( err = func1(); err != nil) || ( err = func2(); err != nil) || ( err = func3(); err != nil) ) { return err } </code></pre> <p>The idea behind such a clause is that execution would break out as soon as a clause would evaluate to false. With Go however, the verbosity increases almost 4x in this particular case:</p> <pre><code>var err error err = func1() if err != nil { return err } err = func2() if err != nil { return err } err = func3() if err != nil { return err } </code></pre> <p>But, what can you do? ;)</p> <p>P.s. check out my blog <a href="https://scene-si.org" rel="nofollow">https://scene-si.org</a> if you liked the above comment. Doesn&#39;t hurt to get a few extra readers :)</p></pre>vem_: <pre><blockquote> <p>I know Go is somewhat verbose. However, you can&#39;t read the code on the video. Is there an experienced gopher who can clarify? Is this example somewhat contrived? Or is Go really that wordy?</p> </blockquote> <p>Go proper is quite verbose due to its lack of generics. The approach most people take seems to be code generation which has some problems.</p> <p>I think comparing Go/Perl is more for educational value than anything else. There aren&#39;t many cases where &#34;should I use Perl or should I use Go?&#34; is a productive question.</p></pre>ops-man: <pre><p>I like Go. It&#39;s a part of my limited tool set - Go, good ole Bash and enough C to get by. I was looking at Perl, Python and perhaps even Haskell as another tool in the box. I wasn&#39;t really looking to compare but while watching this video I just couldn&#39;t help but be distracted after his comparison. </p></pre>vem_: <pre><p>I like Haskell quite a bit. Fast, safe, though the ergonomics compared to go are really not good. It&#39;s a very &#34;tall&#34; language so it can continue teaching you things for a very long time.</p> <p>Python I don&#39;t like anymore. Now that I&#39;ve I started doing Haskell, the only advantage of Python I can see is that compile times are faster (since it isn&#39;t compiled :p).</p></pre>dabshores: <pre><p>Golang&#39;s syntax is not verbose. Look at the horizontal vs vertical alignment for his programs. Languages that encourage horizontal code tend to discourage validation which leads to errors. Go&#39;s mantra is readability and explicit error handling. I doubt the programs he wrote for other languages bothered to check for errors. Therefore, a valid side-by-side comparison would set every error to underscore.</p> <p>verbose:</p> <pre><code>public class foo { public static void main(string args, int argc){ System.out.println(&#34;foo&#34;); } } </code></pre> <p>terse: </p> <pre><code>package main import &#34;fmt&#34; func main(){ fmt.Println(&#34;foo&#34;) } </code></pre> <p>more terse:</p> <pre><code> #!/bin/bash echo foo </code></pre></pre>NeverComments: <pre><blockquote> <p>I doubt the programs he wrote for other languages bothered to check for errors. </p> </blockquote> <p>From <a href="https://www.slideshare.net/Ovid/perl-6-for-mere-mortals" rel="nofollow">the slides of the presentation</a> you can actually see that all the other examples provide the same error handling and constraints.</p></pre>dabshores: <pre><p>I stand corrected!</p></pre>titpetric: <pre><p>Well, from the slides you can also see that Go doesn&#39;t even provide a functioning SetX/SetY, nor that they are invoked from NewPoint or something like Java/others. At least the Go example is flaky at best.</p></pre>
53 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传