TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

I learned seven programming languages

97 点作者 mode80超过 2 年前

22 条评论

tgv超过 2 年前
The author&#x27;s experience is based on toy examples. Programming (and designing) in a professional setting is more than that, though. And the solutions are not the same for everyone: writing an Office plugin has different needs than writing a mobile game. For many of us, the availability of tooling and libraries is crucial. I&#x27;m not going to reinvent the web server by building on OS sockets or write a graphics rendering engine from scratch.<p>That said: Nim does look nice.
评论 #34762509 未加载
评论 #34762444 未加载
评论 #34762925 未加载
pron超过 2 年前
&gt; most programmer convenience is sacrificed on the altar of &quot;never crash&quot;. This makes it a good choice for sending a rocket to space<p>When it comes to safety- or mission-critical software, crashing due to a dangling pointer, a stack overflow or a failed allocation are equally catastrophic, and not crashing but producing a wrong answer due to an algorithmic error is also <i>equally</i> catastrophic. In fact, producing the correct answer <i>late</i> can also be just as catastrophic when the system is real-time -- we don&#x27;t care if the operation takes 1ms or 99ms, but if the deadline for emitting a control command is at 100ms, emitting it 100.001ms late is just as catastrophic as a crash (while completing the calculation in 20ms or 95ms is equally good). Never crashing for <i>any</i> reason, never producing a wrong result, and never producing a correct result late are all <i>equally</i> critical.<p>How are such systems written? They normally require very simple code and very simple algorithms -- to make analysis by tools, and even more importantly, by humans as easy as possible. Any compiler magic or implicitness in the code may be problematic (possibly including reference-counting if a bound on deallocation time cannot be guaranteed). We don&#x27;t want to make code as fast as possible, but as non-surprising and as predictable as possible.
评论 #34763001 未加载
评论 #34762447 未加载
planetis超过 2 年前
I have used Nim for personal projects for 6 years now and it continues to surprise me on how well versed it is for many problem domains. I am fond of it&#x27;s SPA framework, karax <a href="https:&#x2F;&#x2F;github.com&#x2F;karaxnim&#x2F;karax">https:&#x2F;&#x2F;github.com&#x2F;karaxnim&#x2F;karax</a> for which I wrote a translation utility <a href="https:&#x2F;&#x2F;github.com&#x2F;nim-lang-cn&#x2F;html2karax">https:&#x2F;&#x2F;github.com&#x2F;nim-lang-cn&#x2F;html2karax</a> Latest Nimv2 release candidate has improved in the ergonomics and syntax that affect compilation to js, so I was able to cleanup my webapp&#x27;s code to be less verbose. On GPU programming there has been a few projects that touch GPU programming, most notably <a href="https:&#x2F;&#x2F;github.com&#x2F;treeform&#x2F;shady">https:&#x2F;&#x2F;github.com&#x2F;treeform&#x2F;shady</a>
评论 #34763755 未加载
xrayarx超过 2 年前
The author tests the seven languages python, julia, rust, c#, swift, c and nim by programming a Yahtzee bot in each and comparing them. The &quot;winner&quot; is nim.<p>Unfortunately the author only provides the code for nim.<p>So it is subjective based on a simple practical project (1000 locs). Unfortunately it leaves out all the other &quot;cool kids&quot; like crystal, zig, v, dart, d and so forth...
评论 #34763057 未加载
评论 #34762594 未加载
dunefox超过 2 年前
The criticism of Julia seems strange:<p>&gt; But the big dealbreaker with Julia is it only complies on the fly. That means you can&#x27;t just hand a compiled executable to someone. You must give them instructions to install Julia and all your dependencies first. That&#x27;s no good for anything you want to ship like a desktop app or a game. You also don&#x27;t want Julia on your server recompiling with every web request.<p>That&#x27;s an issue with Python as well, but the Julia team is working on that.
评论 #34762774 未加载
评论 #34762880 未加载
maest超过 2 年前
To anyone interested in broadening their knowledge of programming languages, I suggest they should also learn languages from non-imperative paradigms.<p>In particular, functional languages (Haskell, Ocaml etc) and array-based languages (J, q&#x2F;kdb or one of the many free clones out there).<p>Seeing what is capable in those paradigms is very eye opening.
Diti超过 2 年前
I’m surprised about Python being the language OP would teach his kids first. Racket seems more approachable for children.<p><a href="http:&#x2F;&#x2F;emmanueltouzery.github.io&#x2F;blog&#x2F;posts&#x2F;2016-10-13-teaching-racket.html" rel="nofollow">http:&#x2F;&#x2F;emmanueltouzery.github.io&#x2F;blog&#x2F;posts&#x2F;2016-10-13-teach...</a>
评论 #34763789 未加载
jray超过 2 年前
Try crystal!<p><a href="https:&#x2F;&#x2F;crystal-lang.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;crystal-lang.org&#x2F;</a>
评论 #34762522 未加载
tombert超过 2 年前
I have to say, I was quite impressed at the speed of Julia in this test. Getting speeds faster than Rust in a high level language is extremely impressive; maybe I should really make an effort to learn Julia again.
nigamanth超过 2 年前
I was with you till Julia but why C and C++? They&#x27;re OG languages but I can&#x27;t think of one situation where you have to use them for Machine Learning.<p>Out of Python, R and Julia, just learn ONE for 1y and become the best at it. That way, you can build anything in that language and then use that to build something mind-blowing.
dunefox超过 2 年前
Common Lisp might have been interesting to see evaluated here as well.
robochat超过 2 年前
I like nim but I&#x27;ve never really gotten used to the slicing syntax. I guess that I&#x27;m just too used to python, plus you have to be a bit careful to leave a whitespace when doing backwards indexing so that the operators work correctly.<p>So python:<p><pre><code> a = [0,1,2,3,4,5] a[0:5] =&gt; [0,1,2,3,4] - half closed interval a[0:-1] =&gt; [0,1,2,3,4] - negative indexing a[:5] =&gt; [0,1,2,3,4] - skipping start index a[3:] =&gt; [3,4,5] - skipping end index </code></pre> nim:<p><pre><code> var a = [0,1,2,3,4,5] a[0..5] = [0,1,2,3,4,5] - closed interval a[0..^1] = [0,1,2,3,4,5] - closed interval with negative indexing a[..4] = [0,1,2,3,4] - skipping start index a[..&lt;5] - Error - doesn&#x27;t work a[3..] - Error - doesn&#x27;t work a[0..&lt;5] = [0,1,2,3,4] - half closed interval a[0..&lt; ^1] = [0,1,2,3,4] - half closed interval with negative indexing (Important - the white space is required, it will crash otherwise!) </code></pre> I&#x27;m sure that there are good reasons for this behaviour and that if you use nim a lot, you just get used to it but I find the python syntax just nicer.
评论 #34767650 未加载
E17D17ZUVC超过 2 年前
Swift, I was once puzzled by the named function parameter,<p>but then notice later<p>func icon(forFile fullPath: String) -&gt; NSImage<p>func icon(forFiles fullPaths: [String]) -&gt; NSImage?<p>func icon(for contentType: UTType) -&gt; NSImage<p>func with same name, can have different named parameter, and return type.<p>func iconForFile<p>func iconForFiles<p>func iconForContentType<p>Will be the alternative in every other language(paramtype overload is available in c*&#x2F;java&#x2F;kotlin to extent, but it is less explicit), Swift sounds neat isn&#x27;t it?<p>You can see more examples, in particularly class overloads it looks cleaner and convenient to communicate, verbosity is not an issue, code is optimised for reading.<p><a href="https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;appkit&#x2F;nsapplication" rel="nofollow">https:&#x2F;&#x2F;developer.apple.com&#x2F;documentation&#x2F;appkit&#x2F;nsapplicati...</a><p>The actual issue with Swift, is tooling and there&#x27;s SOOOOOO many hidden wanted&#x2F;unwanted &quot;feature&quot;
jbjbjbjb超过 2 年前
I realise this is only a surface level comparison but the Julia code uses the built in factorial function which I think uses lookup tables and the C# version uses a recursive static method, the Python code has your own lookup table. I guess that’s on the hot path? I haven’t taken the time to check if you’ve put a lookup or memoized it somewhere.
kookamamie超过 2 年前
You missed Zig.
jodrellblank超过 2 年前
Complains about words, semi-colons, Julia syntax which prevents writing one-liners, wants a REPL, wants symbols and brevity and optimised numeric work, doesn&#x27;t try APL?<p>Swift: 840 lines<p>Nim: 768 lines<p>C#: 872 lines<p>Julia: 761 lines<p>Rust: 861 lines<p>Python: 550 lines<p>I am curious what a good APL-er [better than me] could do without trying to codegolf it, and how it performs.
Zetobal超过 2 年前
Reads like a guy testing out 30 to do apps to finally get productive.
gbin超过 2 年前
Rust CUDA compilers do exist. <a href="https:&#x2F;&#x2F;github.com&#x2F;Rust-GPU&#x2F;Rust-CUDA">https:&#x2F;&#x2F;github.com&#x2F;Rust-GPU&#x2F;Rust-CUDA</a>
评论 #34771123 未加载
anonzzzies超过 2 年前
Linq expressions are contrived and Python list comprehensions are trivially readable?
Kwpolska超过 2 年前
&gt; It&#x27;s hard to feel happy grinding out a contrived LINQ expression for the same result as a &quot;practically English&quot; list comprehension in Python.<p>I feel the other way. LINQ is great for building pipelines. List comprehensions are kinda like English, but it gets ugly when you use the flattening feature, or when you want something more than just map and filter.<p>Looking at their C# code, they’re going at it in a fairly low-level way, with a lot of aliases for numeric types and a lot of casting between them. For example:<p><pre><code> private static f32 distinct_arrangements_for(DieVal[] dieval_vec) { var key_counts = dieval_vec.GroupBy(x=&gt;x).Select(g=&gt;(g.Key, (u8)g.Count())); uint divisor=1; uint non_zero_dievals=0; foreach (var (key, count) in key_counts){ if (key != 0){ divisor *= factorial(count); non_zero_dievals += count; } } return factorial(non_zero_dievals) &#x2F; divisor; } </code></pre> If you take out the unnecessary number type abuse and just use `int` everywhere, you get something much clearer:<p><pre><code> private static float DistinctArrangementsFor(DieVal[] dievals) { var dievalCounts = dievals .GroupBy(x =&gt; x) .Where(group =&gt; group.Key != 0) .Select(group =&gt; group.Count()) .ToArray(); var divisor = dievalCounts .Select(factorial) .Aggregate(1, (a, b) =&gt; a * b); var nonZeroDievals = dievalCounts.Sum(); return factorial(nonZeroDievals) &#x2F; divisor; } </code></pre> Also, even with all this hard work with weird types, this function has a suspicious return type, since it does integer division and returns a float.<p>There are a few more weird things, like not using switch statements&#x2F;switch expressions, or this function:<p><pre><code> &#x2F;&#x2F; calculate relevant counts for gamestate: required lookups and saves public int counts() { var ticks = 0; var false_true = new bool[] {true, false}; var just_false = new bool[] {false}; foreach (var subset_len in Range(1,open_slots.Count)){ var combos = open_slots.Combinations(subset_len); foreach (var slots_vec in combos ) { var slots = new Slots(slots_vec.ToArray()); var joker_rules = slots.has(YAHTZEE); &#x2F;&#x2F; yahtzees aren&#x27;t wild whenever yahtzee slot is still available var totals = Slots.useful_upper_totals(slots); foreach (var _ in totals) { foreach (var __ in joker_rules? false_true : just_false ){ &#x2F;&#x2F; var slot_lookups = (subset_len * subset_len==1? 1 : 2) * 252; &#x2F;&#x2F; * subset_len as u64; &#x2F;&#x2F; var dice_lookups = 848484; &#x2F;&#x2F; &#x2F;&#x2F; previoiusly verified by counting up by 1s in the actual loop. however chunking forward is faster &#x2F;&#x2F; lookups += (dice_lookups + slot_lookups); this tends to overflow so use &quot;normalized&quot; ticks below ticks++; &#x2F;&#x2F; this just counts the cost of one pass through the bar.tick call in the dice-choose section of build_cache() loop } } } } return (int)ticks; } </code></pre> There are a few weird things, like the pointless foreach loops at the end (which could be replaced with a bit of arithmetic) or the use of a foreach loop where a regular for loop would be better.<p>If this code was rewritten in more idiomatic C#, it could be the basis of a good comparison between languages’ performance and syntax. But I’m not sure if it’s a good example at this point.
评论 #34770113 未加载
blindseer超过 2 年前
&gt; I like named parameters for self-documenting code. Julia allows named parameters but naming them doesn&#x27;t provide any flexibility with regard to their position when calling the function.<p>I don&#x27;t understand this complaint? &quot;Named parameters&quot; i.e. keyword arguments in functions work great in Julia!<p><pre><code> julia&gt; foo(;x = 1, y = 2, z = 3) = x + y + z foo (generic function with 1 method) julia&gt; foo(; z = 4, y = 0) 5 </code></pre> Perhaps the author meant default arguments?<p><pre><code> julia&gt; foo(x = 1, y = 2, z = 3) = x + y + z foo (generic function with 3 methods) julia&gt; foo(3) 8 julia&gt; foo(0, 0, 0) 0 </code></pre> &gt; this flexibility does tend to cause bugs working with other people&#x27;s code. This is compounded by Julia&#x27;s pursuit of composability. If you cram your custom data value into someone else&#x27;s function, and if it seems to be the right shape, it will probably work! Unless it doesn&#x27;t. In that case you just get silently wrong answers. This is a deal-breaker for a lot of scientific computing people where Julia would otherwise shine.<p>This is almost entirely mitigated by most people using `eachindex` or `axes` or other functions that make the array related code index agnostic. The only reason I say <i>almost</i> entirely is because there&#x27;s probably some really old code that doesn&#x27;t work the right way and would silently fail or do the wrong thing if you changed the indexing convention. That said, calling this a &quot;deal-breaker for scientific computing&quot; seems extreme.<p>&gt; I also find Julia&#x27;s errors to be fairly obtuse. And I see a lot of them because dynamic typing means the tools can&#x27;t catch most errors before run-time.<p>I 100% agree. Julia errors are my biggest gripe with the language at the moment.<p>&gt; But the big dealbreaker with Julia is it only complies on the fly. That means you can&#x27;t just hand a compiled executable to someone. You must give them instructions to install Julia and all your dependencies first. That&#x27;s no good for anything you want to ship like a desktop app or a game. You also don&#x27;t want Julia on your server recompiling with every web request.<p>There are packages like PackageCompiler that work pretty well. And I&#x27;m positive in the near future (3 years?) we&#x27;ll have a version of Julia where PackageCompiler will produce small binaries. That said, the convenience of writing in Julia and shipping a precompiled app is pretty awesome, and I personally don&#x27;t mind it taking more space on disk.<p>&gt; Like all compiled languages, the development cycle involves a lot of recompiling as you go. For small programs it doesn&#x27;t matter, but this creeps up as the program grows -- or when you add a heavy dependency, like a plotting library. Julia suffers from this compiled-language drawback, but without the normal advantage of getting a compiled executable you could distribute.<p>This used to be one of my biggest gripes, but things have gotten a lot better with every version of Julia.<p>----<p>My first order approximation when picking a language is this:<p>1) if I think it&#x27;ll be easy to write in Python, I should write it in Julia. 2) If I want to ship a precompiled binary that exposes a command line interface, I&#x27;ll think about using Julia first, and if the size of the binaries are an issue, I might pick Rust.<p>wrt to Nim, I&#x27;m waiting to see how the ORC story shakes out + better documentation about ORC to appear on the scene and for more packages to adopt it. I think Nim currently has too small a community. I&#x27;ve found packages that are commonplace in Rust or Julia are just not even available in Nim. Sometimes a package is 5 years old and hasn&#x27;t been updated. Yes, it is easy to write interfaces but that requires a lot of work. If it is a project where I&#x27;m writing code just by myself, Nim might be a good choice but if I&#x27;m working with someone else, having them learn Nim is much harder. The error messages in Nim also need to get better in my opinion.<p>&gt; You don&#x27;t have to decide between snake_case or camelCase. You can define your variable either way and both references will work. Ditto for most cases of capitalization. I thought this might be problematic, but in practice it&#x27;s brilliant. I think that sentiment applies to many of Nim&#x27;s unexpected design choices.<p>I personally don&#x27;t like this at all. Every time I search a nim codebase, I have to use `nimgrep` instead of using `ripgrep`. I have SO many aliases built on top of things like `ripgrep` and `fzf` and none of them are certain to work in `Nim`. It&#x27;s frustrating that the community is so divided on this, because even though I can see there are benefits to this approach, the benefits pale in comparison to getting user adoption and buy in to use the language.<p>One of my senior developers on my team agreed to learn Nim in their spare time as a favor to me, to evaluate it for a project at work, and as soon as they came across this &quot;feature&quot; they were so turned off, they wrote the language off as being too weird.<p>There&#x27;s a LOT of average programmers out there, and a lot more analysts and data scientists that just want to get shit done, and from personal experience I think it&#x27;s extremely hard to get adoption for Nim in the scientific community. If 7 out of 10 people have used Python, 4 out of 10 people may have heard of Julia and heard that it&#x27;s new and modern, but 0 people have even heard of Nim. I&#x27;ve gotten SO many quizzical looks over the years, it is not even funny.
评论 #34779079 未加载
drewcoo超过 2 年前
And only three were needed for the merit badge!<p><a href="https:&#x2F;&#x2F;scoutlife.org&#x2F;merit-badges&#x2F;programming-merit-badge&#x2F;" rel="nofollow">https:&#x2F;&#x2F;scoutlife.org&#x2F;merit-badges&#x2F;programming-merit-badge&#x2F;</a>