1 Problem, 16 Programming Languages (C++ vs Rust vs Haskell vs Python vs APL...)

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 ก.ค. 2024
  • A video taking a look at 16 programming language solutions (C++, Rust, D, Clojure, Ruby, Elixir, Raku [Perl 6], Haskell, Racket, Julia, Python, APL, J, BQN, Pharo Smalltalk & Fortran) to one problem.
    ADSP Podcast: adspthepodcast.com/
    Array Cast: www.arraycast.com/
    Contest: 255
    Problem Name: Find GCD of Array
    Problem Link: leetcode.com/problems/find-gr...
    Problem Type: Greedy
    Github Links / Chapters:
    0:00 Intro
    1:47 Problem Statement
    2:43 Python: github.com/codereport/LeetCod...
    3:20 Julia: github.com/codereport/LeetCod...
    3:50 Raku: github.com/codereport/LeetCod...
    4:36 Ruby: github.com/codereport/LeetCod...
    5:00 Elixir: github.com/codereport/LeetCod...
    5:34 Haskell: github.com/codereport/LeetCod...
    6:28 Racket: github.com/codereport/LeetCod...
    6:51 Clojure: github.com/codereport/LeetCod...
    7:30 C++: github.com/codereport/LeetCod...
    9:15 D: github.com/codereport/LeetCod...
    9:35 Rust: github.com/codereport/LeetCod...
    10:18 APL: github.com/codereport/LeetCod...
    11:23 Fork / S' Combinator / Starling' / Phoenix
    14:18 J: github.com/codereport/LeetCod...
    15:11 BQN: github.com/codereport/LeetCod...
    16:52 Pharo: github.com/codereport/LeetCod...
    17:32 Fortran: github.com/codereport/LeetCod...
    20:19 Languages not covered
    21:30 Rankings
    26:00 Summary
    26:56 Podcasts and Outro
    Follow me on Github: github.com/codereport
    Follow me on Twitter: / code_report
    Follow me on LinkedIn: / codereport
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 466

  • @Spongman
    @Spongman 2 ปีที่แล้ว +556

    In 30 years programming professionally I have never used gcd in any production code, ever. But good to know it's in the global namespace in so many of these languages.

    • @Levy957
      @Levy957 2 ปีที่แล้ว +48

      Bcz u need a very good reason to use gcd in any code thats not math research related

    • @RobBCactive
      @RobBCactive 2 ปีที่แล้ว +34

      Application specific features like that SHOULD NOT IMO clutter up the core language.
      It should provide the features to use well optimised maths libraries.
      In a game a function sin() might be about players behaving badly rather than mathematical. Reserving names is evil.

    • @CarrotCakeMake
      @CarrotCakeMake 2 ปีที่แล้ว +16

      Well let me explain why. There is only 1 possible way to implement gcd, no one will ever make a better version, and there is only 1 type that gcd can ever be defined for, and the acronym gcd can't possibly ever refer to anything else. That's why we need our betters to put it into the global namespace.

    • @PiroXiline
      @PiroXiline 2 ปีที่แล้ว +1

      @SixTB "Blah blahblah" was speaking sarcastically. And he is right. There can be only one type to do `gcd` on.

    • @PiroXiline
      @PiroXiline 2 ปีที่แล้ว

      @SixTB Ok, you're both trolling, I'm also.

  • @nilstrieb
    @nilstrieb 2 ปีที่แล้ว +308

    I find it interesting that Rust is the only language where you have to explicitly say that this function will crash if you pass in an empty list, I like that.

    • @angeldude101
      @angeldude101 2 ปีที่แล้ว +48

      It's a bit verbose, (and the namespacing should've used `use num::integer::gcd;` on an earlier line) but I absolutely love that Rust forces you to consider the edge cases like that. If any other function gets given an empty list, either they'll just crash unconditionally, or give some kind of weird default value (I think). Rust actually just says "I don't know if the minimum or maximum exist at all so you have to deal with it before you can work with a value that may or may not exist."
      My solution would probably be:
      pub fn find_gcd(nums: &[i32]) -> Option {
      use num::Integer;
      nums.iter().min()?.gcd(nums.iter().max()?)
      // Or maybe
      // Integer::gcd(nums.iter().min()?, nums.iter().max()?)
      }

    • @liesdamnlies3372
      @liesdamnlies3372 2 ปีที่แล้ว +58

      Easily one of the most attractive things about Rust. It’s got speed, but instead of letting you shoot yourself in the foot, it grabs your hand and says “stop it, get some help.”
      Edit: If you absolutely need even more speed, that’s what FFIs are for. But then your thinking will shift into “this is danger zone land, better be careful.” Other programming languages expect you to just stop being a dumb human.
      Well, humans are remarkable flawed. Thirty years of constant security nightmares, so often caused by simply mismanaging strings and their pointers, has shown us that.

    • @nilstrieb
      @nilstrieb 2 ปีที่แล้ว +12

      @@liesdamnlies3372 If you absolutely need more speed you can use unsafe, you don't need FFI.

    • @liesdamnlies3372
      @liesdamnlies3372 2 ปีที่แล้ว +3

      @@nilstrieb You have no idea how hard I just facepalmed at myself just now…dammit…

    • @clyde34
      @clyde34 2 ปีที่แล้ว +12

      @@angeldude101 I'd go with the variant you commented out, since chaining binary mathematical operators becomes really hard to read. Also, cramming everything into one line is unnecesary. It's much more readable when you split it into logical units
      pub fn find_gcd(nums: &[i32]) -> Option {
      Some(num::integer::gcd(
      nums.iter().min()?,
      nums.iter().max()?,
      ))
      }

  • @EnDeRBeaT
    @EnDeRBeaT 2 ปีที่แล้ว +111

    17:33 "And last, but not least, Fortran"
    Last place in actual rankings: Fortran

    • @code_report
      @code_report  2 ปีที่แล้ว +16

      Lmao, fair point.

  • @johndowson1852
    @johndowson1852 2 ปีที่แล้ว +91

    4:36 Ruby is expression based, the last line will be implicitly returned if you leave off 'return'

    • @code_report
      @code_report  2 ปีที่แล้ว +25

      Thanks! I didn't know this!

    • @jaysistar2711
      @jaysistar2711 2 ปีที่แล้ว +25

      @@code_report Ruby also influenced Rust's Lambda expression and return syntax.

    • @rustycherkas8229
      @rustycherkas8229 2 ปีที่แล้ว +1

      I don't know Ruby, but the word "implicitly" in your comment reminds me of "The Elements of Programming Style"
      A Fortran programmer, years ago, wrote 4 lines of comment to document that omitting "END" after the final subroutine was fine because the compiler would see the EOF...
      Laughable...
      The demonstration that all of these languages each have their subtle idiosyncrasies to trip-up newbies is terrifying...
      "Back in my day," said the old man, "when we needed gcd() we spent 10 minutes coding it, not 2 hours lamenting that the language, unlike some others, didn't have a built-in."
      This is the modern implementation of "Jack of all trades (languages); master of none."

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +2

      @@rustycherkas8229 Not really. It's an immediate compiler error because if you forget to return, or put the semi-colon after the last statement (atleast in Rust where the expression must be naked), or put a wrong statement as return, it'll be a type-mismatch. Never encountered such a bug thanks to static typing :)

    • @rustycherkas8229
      @rustycherkas8229 2 ปีที่แล้ว

      @@VivekYadav-ds8oz Dunno... Maybe I'm old... I remember the time before "lint"...
      The good ol' days o' the 'C' Wild West, where "men were real men!" (and the man page for Unix 'cat' was only a few lines!)
      To these old eyes, "One problem; 16 languages (sorry if your favourite was excluded)" rings of "The Tower of Babel"...
      (Moore's Law applied to language population; doubling every 18 months...)
      Once upon a time, the title "Craftsman" was earned by learning and applying ALL the nuances of one's craft...
      I stand by the expression, "Jack of all languages; master of none."

  • @SolarLiner
    @SolarLiner 2 ปีที่แล้ว +76

    The Rust code surprised me a bit, because:
    - The Rust stdlib doesn't have a gcd function, nor a `integers` submodule - this is part of the `num` crate instead, which is an external dependency but has the added benefit that it makes the calculation generic.
    - passing the whole Vec by value is inefficient and leads to the ceremony that you have there on top of being an obvious performance issue - instead, accepting a slice reference allows you to get to `.min()` and `.max()` directly.
    - Rust is a safe language and incentives keeping safety. Making the return value optional leads to a cleaner solution.
    All in all, the better solution (with the num crate) is this:
    fn find_gcd(arr: &[i32]) -> Option {
    Some(num::integers::gcd(arr.min()?, arr.max()?))
    }

    • @halbgefressen9768
      @halbgefressen9768 2 ปีที่แล้ว +2

      Do they have ? for Option now? Nice!

    • @arjentix
      @arjentix 2 ปีที่แล้ว

      It looks a little bit inefficient cause it takes two iteration over arr to get min and max, unlike c++ version with min_max() function. Is there some good alternative of this in Rust?

    • @zyansheep
      @zyansheep 2 ปีที่แล้ว +5

      @@arjentix you would probably have to either write your own .fold() accumulator lambda, or use a library

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +3

      Vec is moved, not copied. Not sure 8*3 = 24 bytes of pointer + data + capacity is much of a performance issue.
      But I do agree that you should take a slice whenever possible, as it makes it possible to interop with a lot more contiguous data structures as possible.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +1

      @@arjentix You would probably need to write your own function for that. Not a big inconvenience, but it would still be nice to have an inbuilt one, y'know? I'm pretty sure that a single PR or RFC on GitHub and it'll be there in the next stable.

  • @rndszrvaltas
    @rndszrvaltas 2 ปีที่แล้ว +284

    One would almost think there will be a comparison of some legitimate code and not literal one-liners using built-in functions...

    • @b2gills
      @b2gills 2 ปีที่แล้ว +9

      You would think so wouldn't you. The thing is that with the languages like APL most code trends towards being a one-liner.
      Raku also trends towards simple expressions. Partly because you can modify the language as you go to make things simpler.
      The languages which are longer have fewer features that allow for this compression of ideas into simple expressions. So they get longer faster.

    • @rndszrvaltas
      @rndszrvaltas 2 ปีที่แล้ว +64

      @@b2gills This is just an excuse, let's be honest. The so-called "challenge" was a not terribly useful or realistic, banal task that you could give a newbie after 10 lessons of programming, even without any built-in function. And having built-in functions for not particularly useful functionalities (talking about general purpose languages) is 1. not a statement about the expressivity of the language in my opinion 2. surely not any relevant when one is to judge which language to use for what task or how effective a language is in a real-life scenario. Like what next? Are we going to compare "Hello World" code snippets?

    • @b2gills
      @b2gills 2 ปีที่แล้ว +5

      @@rndszrvaltas I program regularly in Raku, and I can say with confidence that if I were to translate my code to another language it would be orders of magnitude longer.
      Not to mention the code I write which is not directly translatable. When I write meta code in Raku, that is a feature that is not generally available in other languages. That meta code also allows me to condense and clarify the code further.
      The languages which are longer in this example tend to also be longer in general.
      I have seen a lot of code on the codegolf stackexchange. The general size comparisons among the languages tend to be consistent.
      Actually that's probably a best case scenario for the longer ones. The shorter ones would tend to be shorter anyway.
      When I actively participated, the Raku code was almost always among the shortest of the non golfing languages. There were quite a few times where my golfed code was what I would have written anyway.

    • @rndszrvaltas
      @rndszrvaltas 2 ปีที่แล้ว +18

      @@b2gills I'm not arguing for or against Raku, mind you. Actually, I'm trying to pick up Raku because I like the principles of it and it definitely makes life easier if you need to script Linux.
      That doesn't change anything related to the actual video, though. It's not informative in any way and no, trivial tasks, let alone solved with library functions, do NOT tell anything about the overall verbosity of a language. It tells exactly nothing about the language - or, if anything, whether it's shaped accordingly to this particular task or not.

    • @b2gills
      @b2gills 2 ปีที่แล้ว

      @@rndszrvaltas Raku let's you manage complexity by pushing your complexity into the language. I sometimes write functions which don't have any code in them because the entirety of the complexity needed for the function is handled by just the signature and using multis. Both of which lead to simpler and shorter functions. So this example is actually more exemplary than you might think.

  • @BoyoWhoGoesPoyo
    @BoyoWhoGoesPoyo 2 ปีที่แล้ว +39

    For julia, it is common to use one-line function defs:
    findgcd(nums) = gcd(min(nums...), max(nums...))

    • @PanMaciek
      @PanMaciek 2 ปีที่แล้ว +13

      also in julia you don't need to use variable length argument functions min, max, you can use minimum and maximum to find extrema in array this will improve performance

    • @BoyoWhoGoesPoyo
      @BoyoWhoGoesPoyo 2 ปีที่แล้ว +9

      @@PanMaciek So: findgcd(nums) = gcd(minimum(nums), maximum(nums))

    • @martin2sax
      @martin2sax 2 ปีที่แล้ว +27

      @@BoyoWhoGoesPoyo or even better findgcd(nums) = gcd(extrema(nums)...))

  • @CarrotCakeMake
    @CarrotCakeMake 2 ปีที่แล้ว +67

    The real test of a language is how well it can do things that the language designer wasn't thinking about. Arrays of words and gcd are way too common. Something like shortest path on a graph represented as a matrix would be better. Or something that requires less trivial datatypes like rational numbers or large numbers.

    • @tonyennis1787
      @tonyennis1787 2 ปีที่แล้ว +1

      Your first sentence is akin to faulting a screwdriver because it is a lousy hammer.

    • @CarrotCakeMake
      @CarrotCakeMake 2 ปีที่แล้ว +25

      @@tonyennis1787 No, it is akin to faulting a screwdriver because it doesn't work in cold weather because the screwdriver designer lives in temperate weather.

    • @MultiMrAsd
      @MultiMrAsd 2 ปีที่แล้ว +9

      The real test of a language is: can you come back a year after you wrote the function and quickly understand what it does.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +2

      Wow.. this puts a lot of my problems with certain languages in one sentence. A truly flexible and ergonomical language will excel even in cases not protected and overseen by the designer. I'm inclined to also think C++, but Rust for sure shines a lot here.
      Unless you want to go against the borrow checker, in which case, good luck XD

    • @andrewdunbar828
      @andrewdunbar828 ปีที่แล้ว +2

      @@tonyennis1787 Screwdrivers are not Turing complete.

  • @johndowson1852
    @johndowson1852 2 ปีที่แล้ว +306

    I'd be interested in seeing a Cobol solution in one of those videos. We all hear about how horrible Cobol is, but most of us never seen examples as to why.

    • @ceber54
      @ceber54 2 ปีที่แล้ว +26

      I'd tried to learn Cobol once learning from an IBM course, but essentially i learnt almost nothing. First, you can't run Cobol locally, only runs on IBM mainframes, so to compile your code you must do it remotely. Is tab sensitive, and that is a not for me. If i remember, there not such thing as a for, only goto, something that i only have seen on assembler. Also the compiling routine is awful, you must check before compiling some generated files to look for errors, and then you can compile. is it readable? yes, but by modern standards over-complicated, from COBOL and FORTRAN, i prefer FORTRAN, seems easier.

    • @drew570
      @drew570 2 ปีที่แล้ว +9

      COBOL is an absolutely atrocious language. Some problems are borderline impossible to implement in COBOL so the problems will have to be simple.

    • @watchableraven3517
      @watchableraven3517 2 ปีที่แล้ว +2

      My grandma used to work with COBOL. A procedural oriented language for business. Very cool to hear about it

    • @r.pizzamonkey7379
      @r.pizzamonkey7379 2 ปีที่แล้ว +7

      @@ceber54 Readable? I guess we have different definitions of readable. Compared to Assembly sure, but honestly I find C considerably more readable.

    • @ceber54
      @ceber54 2 ปีที่แล้ว +2

      @@r.pizzamonkey7379 The argument of why the sintaxis of cobol is how it is, is because the code should be audited by someone not expert in the code, or at least that was the initial idea. That what it means when "cobolist" refer Cobol as readeable. But yes C, or even Fortran, is easiest to understand at first glance than Cobol. Personally I don't think that cobol is readeable.

  • @ebn__
    @ebn__ 2 ปีที่แล้ว +49

    liftM2 takes a function (a -> b -> c) and returns a function (f a -> f b -> f c), (f : Monad)
    note that you don't need the monad constraint since maximum does not rely on the result of minimum or vice versa - and could just use liftA2 from Control.Applicative - not that it matters in this case but Monad is sequential where as solution using Applicative could be made to be parallell.
    or: gcd minimum maximum

    • @w-mwijnja8919
      @w-mwijnja8919 2 ปีที่แล้ว +11

      To be honest, this is the kind of situation where I think that using applicative or monadic abstractions does not make the result more clear (because the applicative/monad instance for functions is one of the harder ones to grasp). I prefer a less feature-heavy solution like
      ```
      findGCD2 nums = gcd (minimum nums) (maximum nums)
      ```
      Of course this is subjective :-).

    • @Yotanido
      @Yotanido 2 ปีที่แล้ว +4

      @@w-mwijnja8919 I generally agree, but I think using the applicative operators and is plenty readable. Especially since this sort of pattern comes up a decent amount of time. At least in my code.

    • @neclitorismagnum
      @neclitorismagnum 2 ปีที่แล้ว

      Monad is not necessarily sequential. Computations that don't depend on each other can be evaluated in arbitrary order.

  • @francisking708
    @francisking708 2 ปีที่แล้ว +256

    "Languages should have GCD in the core library" - why? How often does the average programmer use this?
    Fortran is great for programming array programs across multiple cores and servers - Julia is the modern alternative.

    • @fburton8
      @fburton8 2 ปีที่แล้ว +9

      Good question. I'd love to see some examples of gcd use in real life problem solving.

    • @hemangandhi4596
      @hemangandhi4596 2 ปีที่แล้ว +14

      That too, then he docks BQL for this despite it decently explaining why it doesn't have a GCD built-in.

    • @ZReChannel
      @ZReChannel 2 ปีที่แล้ว +3

      Maybe once every ten years

    • @hanyanglee9018
      @hanyanglee9018 2 ปีที่แล้ว

      @@ZReChannel I guess this is the reason that I started learning programming in 2015 and don't know what GCD is today.

    • @sebastienleblanc8613
      @sebastienleblanc8613 2 ปีที่แล้ว +20

      When you have to display fractions to a user, you can easily reduce a fraction using GCD. 14/21 reduces to 2/3 because (gcd 14 21) = 7, so (14/7)/(21/7) → 2/3.
      Not finding a use for something does not make it inherently useless.

  • @flyingsquirrel3271
    @flyingsquirrel3271 2 ปีที่แล้ว +131

    At this point I think you are cherry picking these challenges so they are elegantly implementable in apl xD
    I would love to see a medium level leetcode exercise (even if its fewer languages then)

  • @glynnec2008
    @glynnec2008 2 ปีที่แล้ว +58

    @3:26 A better Julia solution IMHO is
    find_gcd(nums) = gcd(extrema(nums)...)
    NB: The splat operator (...) goes after the call to extrema, not on the nums array itself.

    • @red13emerald
      @red13emerald 2 ปีที่แล้ว +3

      Julia is such a beautiful language, this is incredibly easy to read and terse as hell. I’m reading through the docs right now, can’t wait to find a project I can actually use it on.

    • @oxey_
      @oxey_ 2 ปีที่แล้ว

      that's cool

    • @brettknoss486
      @brettknoss486 2 ปีที่แล้ว +1

      I'm not sure if the method is needed. If nums is already defined then it isn't. This video is misleading, if it doesn't show how a function is called, or how the array is defined.

  • @remyclarke4020
    @remyclarke4020 2 ปีที่แล้ว +69

    I'm so glad you were a good sport and gave Fortran a go, it gives a nice contrast to the other languages.

  • @RunningBugs
    @RunningBugs 2 ปีที่แล้ว +19

    It's nice to learn what it looks like to program the same simple problem using different languages, although I really don't think it's necessary to put a ranking part in the video, I've no idea what that part is for.

  • @Possseidon
    @Possseidon 2 ปีที่แล้ว +14

    You can simplify the C++20 a tiny bit further by using "minmax" instead of "minmax_element", which directly returns the two values instead of their iterators, sparing you from doing the dereferencing. The old non-ranges minmax only works with two values (or an initializer list) unfortunately, so this only work with C++20 ranges.

    • @VamoAComeLaPapa
      @VamoAComeLaPapa 2 ปีที่แล้ว

      std::minmax receives just 2 elements. Here you need to receive a sequence of elements.

    • @Possseidon
      @Possseidon 2 ปีที่แล้ว

      @@VamoAComeLaPapa I was talking about C++20 std::ranges::minmax, which does take a whole range. I even mentioned your very same issues with the old std::minmax in the final sentence? :)

    • @VamoAComeLaPapa
      @VamoAComeLaPapa 2 ปีที่แล้ว +2

      @@Possseidon yes, you are right, it seems that one of the overloads of std::ranges::minmax is an alias for std::ranges::minmax_element
      Thanks!

  • @haydermabood
    @haydermabood 2 ปีที่แล้ว +9

    I love that Smalltalk is added to the mix! Please consider Idris in the future too.

  • @ingenium5831
    @ingenium5831 2 ปีที่แล้ว +22

    Why Fortran is so popular? Because it is still a thing if you are number crunching :-) using Fortran with OpenMP and MPI on big clusters is a thing e.g. for climate models, aerodynamics, optimization, and other science and engineering stuff.
    And wrt your question of how to pass an array without passing a the size first: Assumed shape arrays
    Declare it as:
    INTEGER, DIMENSION(:) :: nums
    Like this the subroutine expects a 1-dimensional array which has been allocated before. For 2D it would be DIMENSION(:,:) etc.
    Btw: the IMPLICIT NONE would usually be put on top of you MODULE and thus you do not repeat it in all functions or subroutines.

    • @code_report
      @code_report  2 ปีที่แล้ว +9

      Honestly, the responses from the Fortran community here and on Twitter have been amazing! I am definitely going to be doing a follow up video.

    • @pavelperina7629
      @pavelperina7629 2 ปีที่แล้ว +2

      I'm quite surprised, I expected it's dead for 30 years and replaced by Pascal, C, ....
      Last 15 years Python is extremely popular, but it's painfully slow. C++ misses any useful standard libraries for image processing, worker thread pools, parsing even most basic files (ini, csv, xml, ...) and standard template library is like 100x slower in debug mode (at least one that comes with Microsoft Visual Studio and contains extra error checking). It's quite painful to setup build environment for extra libraries. I've just discovered Julia week ago and I think I may use it for some projects (already wrote 600 lines of data crunching code and it seems ok)

    • @ingenium5831
      @ingenium5831 2 ปีที่แล้ว +5

      @@pavelperina7629 30yrs ago, the fortran90 standard has been released which has made a huge step from F77 (which I have never used, I have only to understand it sometimes when debugging in the ancient parts of our software :-D computed GOTO... arg).
      And if you check modern standards like 2003 or 2008 which introduced object oriented features like inheritance etc, or native parallel stuff like DO CONCURRENT, you have a modern language (the OOP stuff feels a bit cumbersome to be used, but it works fine).
      I think it is a fine language for the number crunching work, but I'm no IT guy, but a mechanical engineer who codes 🙂

    • @astroid-ws4py
      @astroid-ws4py 2 ปีที่แล้ว +3

      @@pavelperina7629 Fortran is still well alive, Soon an official LLVM Fortran compiler called Flang will be released, and an interactive LFortran compiler is currently in the works, And also there are high quality Fortran compiler from Intel and Nvidia called Ifort and NVFortran respectively, So it is well alive, But I guess they need to do some updates to the standard, Maybe add generics, templates, meta-programming, tuples, lambdas to the language, After that it could be a fun language to work with which could be substituted for the likes of C++ or Rust for certain systems level programming tasks

    • @kekaci
      @kekaci 2 ปีที่แล้ว +3

      @@ingenium5831 I've used f77, and even f60. They're fun, but pretty unusable. f90+ is definitely the best experience

  • @gagansrai8137
    @gagansrai8137 2 ปีที่แล้ว +35

    you can use the java interop with clojure and remove the import
    (defn find-gcd [nums]
    (.gcd (biginteger (apply min nums))
    (biginteger (apply max nums))))
    but tbh this problem is trivial, judging a language on the fact that it doesn't have gcd in its stdlib and "too many parens" is a bit silly.
    also the above solution took me 20 seconds of experimenting in the REPL. The haskell solution was beautifully elegant, APL was a bit too cryptic for me.

    • @jonseltzer321
      @jonseltzer321 2 ปีที่แล้ว +3

      I would add that Clojure benefits from the JDK ecosystem - the largest library ecosystem of all 16 of these languages

    • @andrewlalis
      @andrewlalis 2 ปีที่แล้ว +1

      @@jonseltzer321 this is why it's been hard for me as a Java developer to transition to D and other small languages that have a better design, but a much smaller ecosystem

    • @jonseltzer321
      @jonseltzer321 2 ปีที่แล้ว

      @@andrewlalis Agree, that's why I don't understand why you don't have a 'Haskell for the JVM', or 'APL for the JVM'.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +2

      Damn Clojure was pretty smart to keep backwards compatibility in such a simple way. No extern "Java" crap, just simple 'yeah just name the library. meh.'

  • @pak-9
    @pak-9 2 ปีที่แล้ว +80

    Your opinion of each language and its solution seems to be based entirely on brevity and elegance. If I saw any of these solutions in a production code review I would ask for them to be heavily commented to explain their function and to aid readability.
    There is nothing wrong with judging a language subjectively but it would be helpful to explain your criteria for judgement somewhere in the video.

    • @xGOKOPx
      @xGOKOPx 2 ปีที่แล้ว +9

      If you think that these solutions have to be heavily commented then I don't think the solutions are the problem here

    • @sunglow9835
      @sunglow9835 ปีที่แล้ว

      you should look at 1:24 where he says he is ranking these "from favorite to least favorite"

    • @JackDespero
      @JackDespero ปีที่แล้ว +1

      @@xGOKOPx If someone sent me any of the array language solutions, I would automatically reject them and answer that a cat run over their keyboards, apparently.

    • @xGOKOPx
      @xGOKOPx ปีที่แล้ว +2

      @@JackDespero I was talking about the solutions from more conventional languages here. They're all pretty readable if you have basic familiarity with the concepts (although C++ namespaces do create some visual noise).
      And if you were in a position where someone sends you a solution written in an array language and you can accept or reject it, then you'd probably know that language, so it would be readable to you as well

    • @qwerte6948
      @qwerte6948 ปีที่แล้ว

      ​@@xGOKOPx dude like youll be able to read last few ones 💀
      personaly it doesnt matter the language if your writing code in rust, C or phyton becouse theyll just get compiled to binary anyways... simply readable easy language > cryptic language especially if your working with a team of people

  • @burnytech
    @burnytech 2 ปีที่แล้ว +92

    People that requested Fortran wanted to see you suffer :D

    • @cobaltno51
      @cobaltno51 2 ปีที่แล้ว +8

      well, they could have just asked for x86 assembler

    • @Acaykath
      @Acaykath 2 ปีที่แล้ว

      @@cobaltno51 Or code it purely in nand based boolean logic for real bare-metal level programming.

    • @anton7354
      @anton7354 2 ปีที่แล้ว

      @@cobaltno51 Ever heard of ARM SVE2? Or Itanium for that matter? :-D

  • @flow5718
    @flow5718 2 ปีที่แล้ว +10

    As a python programmer, I really liked Ruby's syntax.

  •  ปีที่แล้ว

    great video, thanks for the huge effort putting this together! at the end comparison part it would be nice to see the code popping up when you select the languages. also i'd be interested in runtime comparison as well :D

  • @RSDonovan
    @RSDonovan 2 ปีที่แล้ว +6

    Your idea of a low-level language is different to mine. I used 360/370 assembler in a 30 year coding career 😊 PS Love the array cast podcast

  • @edo9k
    @edo9k 2 ปีที่แล้ว +14

    I really like your videos, I learned of APL's existence from content you create (here and the podcasts).
    But in most of the examples you choose, APL seems to excel because they're usually in the domain area that fits APL/J/BQN: transforming a list, or reducing it to a response.
    I'd like to see you address the other side. Problems for which APL is not a good choice.

    • @MrAbrazildo
      @MrAbrazildo ปีที่แล้ว

      This comment should be pinned.

  • @Sumospider
    @Sumospider 2 ปีที่แล้ว +6

    Not sure if it has been mentioned already, but in the Julia version, you want to use the minimum function instead of min for arrays. Or even better here, the extrema function to give you both minimum and maximum.
    ```julia
    gcp(extrema(vector)...)
    ```

    • @tubesteaknyouri
      @tubesteaknyouri ปีที่แล้ว

      I was about to make the same comment.

  • @davedoublee-indiegamedev8633
    @davedoublee-indiegamedev8633 2 ปีที่แล้ว +5

    For part 2, we need SQL or PL/SQL, some version of Assembly, Bash, Prolog, Scratch, Piet and Cobol!

  • @Cleanblue1990
    @Cleanblue1990 2 ปีที่แล้ว +5

    I know people from the department of theoretical solid body physics that use Fortran a lot. They have all their packages written in it and they need it for the performance to simulate just a few % more atoms at the same time.

  • @ahmedbouali7000
    @ahmedbouali7000 2 ปีที่แล้ว +1

    This channel is pure gold : )

  • @chudchadanstud
    @chudchadanstud 2 ปีที่แล้ว +6

    Me when looking at APL: Where are those keys on my keyboard?

    • @oxey_
      @oxey_ 2 ปีที่แล้ว

      yeah those languages are completely unreadable and seer really hard to write. I know nothing about them, perhaps they're great. On first glance though I thought I was looking at brainfuck lol

    • @kruksog
      @kruksog 2 ปีที่แล้ว

      @@oxey_ if you have a solid understanding of mathematics and lambda calculus, it's not bad at all.

  • @AahhBurnedToast
    @AahhBurnedToast 2 ปีที่แล้ว +3

    I kinda wanted to see you implement your own solution in all the languages but sure, you could do this too

  • @jeffreyhuang3249
    @jeffreyhuang3249 2 ปีที่แล้ว +13

    This is extremely nit-picky but for your python solution nums should be type annotated with list[int], not List[int]. PEP 585 makes it so the lowercase version is the generic and List, Tuple, etc are going to be deprecated

    • @m.sierra5258
      @m.sierra5258 2 ปีที่แล้ว

      Same for rust, Vec[u32] should be &[u32]

  • @tcbrindle
    @tcbrindle 2 ปีที่แล้ว +4

    It's been a long time since I've done any Fortran, but from memory you declare an array argument using the syntax nums(:) (or my_matrix(:, :) for a rank-2 array etc). Also, you don't need to explicitly name the output variable for a function -- it defaults to the function name, so you can say
    integer function find_gcd(nums)
    integer, intent(in) :: nums(:)
    find_gcd = gcd(minval(nums), maxval(nums))
    end function find_gcd
    implicit none can go at the module level so you don't need to say it in every function, or you can use a compiler switch to apply it everywhere (-fimplicit-none or something like that?)

  • @pascal7947
    @pascal7947 2 ปีที่แล้ว +4

    Clojure could also just call out to Java:
    (defn gcd [a b]
    (.gcd (biginteger a) (biginteger b)))

  • @saeidgholami2795
    @saeidgholami2795 2 ปีที่แล้ว +3

    I'm interested with programming languages specially their syntax so I really like this series of videos. What I want to see is that compare this languages in a real world programs like a simple game or simple blog website or other type of applications.

  • @cc.jsullivan
    @cc.jsullivan 2 ปีที่แล้ว +1

    6:51 for the Clojure solution, it might just work if you change the symbol `math.gcd` to `math/gcd`. The slash is how you access vars from a namespace, which is how functions are interned/accessed as well.

  • @UberOcelot
    @UberOcelot 2 ปีที่แล้ว +14

    Definitely inspires me to check out APL/J. I'm a big fan of Rust/Idris but I'd like to branch out a bit more. Would have liked to see Prolog shown off, hopefully we see it more in future videos.

    • @code_report
      @code_report  2 ปีที่แล้ว +5

      Prolog will definitely get highlighted in the future!

  • @jacobcohen76
    @jacobcohen76 2 ปีที่แล้ว +1

    C++ 20's std::ranges has a minmax for value types. Also the returned structs are compatible with structured bindings.
    int find_gcd(std::vector nums) {
    const auto [min, max] = std::ranges::minmax(nums);
    return std::gcd(min, max);
    }

    • @petermuller608
      @petermuller608 2 ปีที่แล้ว

      Imo the solution shown was nicer

  • @jansuran5442
    @jansuran5442 ปีที่แล้ว +1

    7:05
    Namespace qualified symbols in Clojure use a forward slash as the separator, which can also be used for accessing static members such as (Math/min 1 2) or Math/PI. The standard dot is used in non-static method/constructor host interop (although (. Math PI) would also work), where the syntax is also a bit different: (.toString (.append (StringBuilder.) "foo")) or (.. (StringBuilder.) (append "foo") toString) with the double-dot macro which both expand to (. (. (new StringBuilder) append "foo") toString) anyway.

  • @flipytube
    @flipytube 2 ปีที่แล้ว +10

    You don't need the elipses in Julia if you use the functions minimum and maximum instead of min and max

    • @stillyslalom1
      @stillyslalom1 2 ปีที่แล้ว +10

      Better yet, `extrema`, which enables this: `find_gcd(nums) = gcd(extrema(nums)...)`

  • @w-mwijnja8919
    @w-mwijnja8919 2 ปีที่แล้ว +4

    I would be very much interested in which languages have a specialized `minmax` function to calculate both the minimum and the maximum in a single-pass, which languages ('s compilers) are smart enough to optimize separate calls to `minimum` and `maximum` into a single pass regardless, and in which languages you will be stuck with a solution having multiple passes over the collection.
    The results probably are not that useful for practical programs (as this is a micro-problem of course), but I'm still curious :-).

    • @ralphmellor1909
      @ralphmellor1909 2 ปีที่แล้ว

      There's a comment above showing Ruby and Raku using an explicit `minmax`.

  • @qm3ster
    @qm3ster 2 ปีที่แล้ว +1

    The transition between C++17 and C++20 was really wack (look at that `nums` go!)
    Was there any way to adjust that by hand?
    What do you use for those?

  • @RepublikSivizien
    @RepublikSivizien 2 ปีที่แล้ว +14

    Now Rust with generics and you can use any integer type and without unwrap, it is panic-free if the input is empty. Not sure, how the other languages handle this:
    use itertools::*;
    use num::*;
    pub fn find_gcd(nums: T) -> Option {
    let (min, max) = nums.minmax().into_option()?;
    Some(max.gcd(&min))
    }

    • @NoNameAtAll2
      @NoNameAtAll2 2 ปีที่แล้ว

      does rust not have an unwrap? why can't one pass the '.into_option()?' tuple as 2 parameters of gcd?

  • @jmpjns2497
    @jmpjns2497 2 ปีที่แล้ว

    What font are you using in the code examples

  • @raphaelcardoso7927
    @raphaelcardoso7927 2 ปีที่แล้ว

    What was that python solution? Arrows? Self in a function outside a class? Can someone pls explain? Ty

  • @antoniohg
    @antoniohg 2 ปีที่แล้ว

    Very cool video!

  • @VonCarlsson
    @VonCarlsson 2 ปีที่แล้ว +4

    A note about the Rust code: declaring a parameter's type as T (as opposed to &T) is a guaranteed move unless T implements the Copy trait. Any subsequent use of the value passed to the function would result in a compile time error. As such &[i32] would've been a more appropriate parameter type (or &[T] where T: Integer + Copy).

    • @CarrotCakeMake
      @CarrotCakeMake 2 ปีที่แล้ว

      Clone instead of Copy would give a solution that works for large number types.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +1

      @@CarrotCakeMake finding .max() or .min() don't require any sort of copy, as the internal .cmp() function takes its comparison numbers by reference anyways. &[T] where T: Integer is good enoughl.

    • @CarrotCakeMake
      @CarrotCakeMake 2 ปีที่แล้ว

      @@VivekYadav-ds8oz Ord::max/min returns the same type it outputs, so it either has to clone or return a reference. num::integer::gcd requires ownership of an integer type. So you have to clone sometime, but you could get away with it by doing a gcd(found_min + 0, found_max + 0) maybe. Having gcd require ownership seems like a mistake unless there is a really good optimization that comes from it.

  • @thesupercomputer1
    @thesupercomputer1 2 ปีที่แล้ว

    Might it be possible in Future to compare also the speed of the languages? :D
    I'm familiar with C++ and know it's fast, when you know what you do.
    But I'm interested in how much faster it is, or might it be in some circumstances be slower?

  • @AggressiveMenace
    @AggressiveMenace ปีที่แล้ว +1

    Years ago I use to think on Rust just as a "another programming language, such as many others". Nowadays I'm surprised by the evolution either as the language itself and their community, as well as their applications. Unquestionably has a long future for embedded systems, kernel source code (+6.* Linux kernel is a clear example of this), general purpose development, even for networking APIs, and basically an interesting replacement for C++ and Java for OOP.
    Rust is the present but it's the future too, I trust with absolute hype this can be useful as C language and other classic languages, basically it's a swiss army knife.

  • @mytech6779
    @mytech6779 2 ปีที่แล้ว +1

    Fortran is tops for massive parallel super computing and the fortran linear algebra libraries are rock solid and proven bug free for decades so the results can be relied on. (by massive I mean single computations that take $50,000 in electricity for each run.)

  • @gfldex4772
    @gfldex4772 2 ปีที่แล้ว +4

    For Raku, storing a list in a scalar may lead to surprises. Also, gcd can be an infix operator, but doesn't have to.
    sub find-gcd (*@nums where (@nums.all ~~ Numeric or fail(‚I don't know how to find a gcd for a non-number.‘))) {
    [gcd] .min, .max with @nums
    }
    This reads: force the argument list into a list and check if it contains a number. Return the gcd of the smallest and largest element of that list.
    Raku is smart enough to deal with lists of strings. So the check against Numeric serves as basic input validation. We would get a not so nice runtime error by min without the check in the signature.

    • @MogTM
      @MogTM 2 ปีที่แล้ว +1

      imo, if you're going to use `with` anyway, you might as well skip the reduction and use &gcd as an infix operator: .min gcd .max with @nums # but TIMTOWTDI, of course

    • @zengargoyle
      @zengargoyle 2 ปีที่แล้ว +2

      raku -e 'say {[gcd] .minmax}(2..10)'
      2
      Yeah, we got the good stuff.

    • @MogTM
      @MogTM 2 ปีที่แล้ว

      @@zengargoyle oh, interesting - I didn't realize that Range.minmax returns a List (unlike Any.minmax, which returns a Range). So to accept Arrays as input, you need .minmax.bounds (or, I guess, .minmax.minmax - which is a pretty odd construction!) but if we only need to accept a range then your one-liner works. I wonder why Larry et al. decided to have the two .minmax methods return different types?

  • @holthuizenoemoet591
    @holthuizenoemoet591 2 ปีที่แล้ว

    Infix functions like the example in perl are realy nice to type. thats cool

  • @john.dough.
    @john.dough. 2 ปีที่แล้ว +2

    4:52 -> It's interesting to see you talk about the implicit return in Raku, and then not use it in Ruby.
    you could have written
    ```rb
    def find_gcd(nums)
    nums.max.gcd(nums.min)
    end
    ```
    or even
    ```rb
    def find_gcd nums
    nums.max.gcd nums.min
    end
    ```
    if you don't like parenthesis (although, personally, I would keep them in)

  • @jabuci
    @jabuci 2 ปีที่แล้ว +1

    In Julia there are maximum() and minimum() too that get a collection, thus no need for the splat operator. And extrema() also exists, thus C++ is not the only lang. that can return both the smallest and largest elements.

    • @code_report
      @code_report  2 ปีที่แล้ว +1

      Yep, I cover that in a follow up video.

  • @iuliandumitrache7307
    @iuliandumitrache7307 2 ปีที่แล้ว +5

    Seams like a lot of features have been added to C++ recently. Any recommendations for someone who wants to get familiar with them?

    • @pavelperina7629
      @pavelperina7629 2 ปีที่แล้ว +1

      Lol, I guess you can't. There's too many things in C++ so you can't know all of them. On the other hand very basic things are missing. I'd like to know how to upper-case unicode string, how to sort strings according to locale etc, thread pools,...
      What I would recommend is either fmt library (3rd party) or std::format (most used functions of fmt made it into c++20) because and are pain.

    • @MaxHaydenChiz
      @MaxHaydenChiz 2 ปีที่แล้ว +3

      "A Tour of C++ (second edition)" seems to be your best bet. Lots of the stuff you are seeing has been available for a long time via libraries (Boost, various proposed extensions, etc.), but they are adding them to the language and removing a lot of the ceremony around using them which is nice. The language updates every 3 years, and you can use the "beta" versions of stuff earlier than that. So, keeping current is a lot.

    • @hmm7458
      @hmm7458 2 ปีที่แล้ว

      bruh believe me.. it would be better if you don't go down the rabbit hole of C++ it have no ending this language have so much that even pros don't know everything of it

    • @az-kalaak6215
      @az-kalaak6215 ปีที่แล้ว

      read the documentation, code side-projects and do not use last cpp version as compilers are inconsistant in their implementation (cpp20 is currently not fully implemented in clang and gcc).

  • @LeandroCoutinho
    @LeandroCoutinho 2 ปีที่แล้ว +19

    Very nice! I thought you were going to write the gcd function, but it would be too long ... Maybe you could write for the 5 languages you like most. =)
    The C++ single pass is neat, and maybe it deserved a better rank because of that. :)

    • @petermuller608
      @petermuller608 2 ปีที่แล้ว

      To be honest, most other languages have a minmax function, too ;)

    • @landsgevaer
      @landsgevaer 2 ปีที่แล้ว +1

      The gcd part can be done recursively quite easily using pseudocode like
      gcd(x,y) = (if y == 0: x, else: gcd(y, x mod y))
      I would also have preferred finding the gcd of *all* numbers in the array, instead of the min&max.
      To be honest, the way it is now, the video more or less boils down to "which language has the most succinct gcd and minmax syntax".
      And I hate it when programmers' kneejerk reaction is to require builtins for even simple tasks.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +1

      It would, if that was something truly revolutionary or hard to implement yourself.

  • @VivekYadav-ds8oz
    @VivekYadav-ds8oz 2 ปีที่แล้ว +1

    Ngl I expected Fortran to look much more arcane like COBOL. It's surprisingly familiar

  • @JasonDoege
    @JasonDoege 2 ปีที่แล้ว

    It seems to me that the Raku solution is essentially the same as the APL, J, BQN, and Pharo solutions, the commonality being GCD being an infix operation which permits expressing the solution in a Fork idiom.

  • @sabanin
    @sabanin 2 ปีที่แล้ว +2

    You can simplify the Ruby solution by removing the explicit "return."

  • @qm3ster
    @qm3ster 2 ปีที่แล้ว +5

    I was sure you'd put Fortran in the first place for lulz

  • @varantavers
    @varantavers 2 ปีที่แล้ว +1

    I might be wrong, but julia has the minimum and maximum functions too, that way you don't need the elipsis.

  • @jmhimara
    @jmhimara 2 ปีที่แล้ว +4

    Fortran would also be as fast as the C++/Rust solutions (or even faster, sometimes). Being a very old language it has some baggage that can throw people off (including its verboseness, which CS people hate, though scientists tend to like) ..... but I'm also curious about how much time you spent on the Fortran solution. One of Fortran's redeeming qualities is that it's a ridiculously easy language to learn. I've trained many grad students in it, and even those with no programming experience to learn it within a day (not all of it, but most of what they need to write scientific code).

    • @jmhimara
      @jmhimara ปีที่แล้ว

      @Delyan Kirov c++

  • @tonyennis1787
    @tonyennis1787 2 ปีที่แล้ว

    Very good!

  • @FeLiNe418
    @FeLiNe418 2 ปีที่แล้ว

    How do you type in APL symbols

  • @zcubesdemoes2191
    @zcubesdemoes2191 2 ปีที่แล้ว

    In z^3, x=>GCD(MIN(x),MAX(x)) x can be an array of any shape. z^3 is Array based like APL.

  • @vonBottorff
    @vonBottorff 2 ปีที่แล้ว +6

    Somebody needs to write a book on point-free. Every time I've seen it in Haskell it looked like doing a root canal on yourself without anesthesia. I know it's part of the whole March of Category Theory, but really . . . Yeah, any advice welcome.

    • @qandak
      @qandak 2 ปีที่แล้ว

      There is nothing to do with Category Theory. Only higher order functions with lazy/partial evaluation.
      You can easily read things like "f = g h" as an aliasing. Everything passed to the "f" (if expected by type) will be passed to the right-hand side :)

    • @vonBottorff
      @vonBottorff 2 ปีที่แล้ว

      @@qandak But isn't "point-free" another name for Category Theory?

    • @qandak
      @qandak 2 ปีที่แล้ว

      @@vonBottorff Nop

    • @argh44z
      @argh44z 2 ปีที่แล้ว

      @@vonBottorff No. APL is far more point free than something like haskell, for example. Other way to think about point free is how julia does it (multidispatch), which is also emutable with anything w/ dynamic dispatch with type Any.

    • @0LoneTech
      @0LoneTech 6 หลายเดือนก่อน

      Point free means you're working on entire spaces and transformations, rather than individual points within them. That usually takes the form of removing arguments that are simply repeated; e.g. addone x = 1+x translates to addone = (1+). x here is a placeholder for one particular point, while its type is the domain the function can operate on. In practice it's just decluttering the data paths, hopefully letting us consider our operations at a higher level.
      revwords line = let
      ws = words line
      rws = map reverse ws
      result = unwords rws
      in result
      revwords line = unwords (map reverse (words line))
      revwords = unwords . map reverse . words
      -- . is the ∘ combinator for unary (aka monadic) function composition, pronounced "of"
      revwords "olleH !dlrow"
      This simple example relied on the input argument only occurring once, at the end. If that's not the case we might want to use combinators like liftA2, flip or const (map is a second order combinator, operating across a whole list). Building such combinators is where lambda calculus kicks in, the overly mystified art of variable substitution. The mere fact we can leave arguments out is because we have partial application and first class functions.
      Point free style in Haskell is like tacit style in APL, but APL has more combinators built into its syntax.
      Category theory is usable to describe function compositions, but does not on its own relate to source text, which is where style like point free is expressed.

  • @hz3ynp4
    @hz3ynp4 2 ปีที่แล้ว +1

    the auto-generated CC subtitle was wrong, it translated English into Vietnamese from audio directly.

  • @pythonprojectsforwindows6795
    @pythonprojectsforwindows6795 2 ปีที่แล้ว +1

    missing import for Python
    import math
    my version of Python requires an import for List but you can replace List[int] with list to avoid another import.

  • @whatthehelliswrongwithyou
    @whatthehelliswrongwithyou ปีที่แล้ว +1

    You could have added type signature in haskell that would be pretty general since every function requires only Ord a, (yes, including gcd)

  • @petermuller608
    @petermuller608 2 ปีที่แล้ว +1

    Can you require a non empty array as argument to get rid of the .unwarp calls in Rust?

    • @angeldude101
      @angeldude101 2 ปีที่แล้ว +2

      There's not really a way to prove that to the compiler. A better solution would be to just accept that you'll return an Option and use the `?` try operator. The solution is cleaner and more general.
      It's theoretically possible with const generics, but proving at compile time to never have an empty list would be several times longer than leaving it as is.

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 2 ปีที่แล้ว +2

      I think you can do that with const generics, but it'll be uglier than this. As much as I like the Haskell philosophy of making all unwanted states unrepresentable by making all such errors compile-time, you have to balance that with the maintainability of the code, the increased compilation time, the poorer generic error messages, and if it's really worth to push the runtime error to compile time. In this case, not really, as it can be handled in runtime just as smoothly.

  • @TheShulg
    @TheShulg 2 ปีที่แล้ว

    how would it look like in whitespace?^^

  • @tricky778
    @tricky778 ปีที่แล้ว

    Haskell: findGCD = gcd minimum maximum
    Or giving a maybe in case of empty list: findGCDM = fmap findGCD . nonEmpty
    () Is the S combinator when applied to functions
    () is the B combinator when applied to functions. It's fmap in operator form, and (.) With different associativity and precedence.

  • @dibyojyotibhattacherjee4279
    @dibyojyotibhattacherjee4279 2 ปีที่แล้ว

    Yo, what's your favourite ide to use c/c++ development?

    • @code_report
      @code_report  2 ปีที่แล้ว +2

      I typically use VS Code for versatility across languages. I spent the first 4 years of my career in Visual Studio and that is a world class C++ IDE.

  • @CarlosYounes
    @CarlosYounes 2 ปีที่แล้ว

    Thanks
    Very Nice
    Congratulations from Brasil
    Best Regards :)

  • @davewebb1115
    @davewebb1115 2 ปีที่แล้ว

    so many interesting comments!

  • @cmr2079
    @cmr2079 2 ปีที่แล้ว

    How do you even type APL code?

  • @rheemboi
    @rheemboi 2 ปีที่แล้ว

    You could also use tuples as argument in the c++

  • @rcsz229
    @rcsz229 2 ปีที่แล้ว +1

    The point of FORTRAN is that specific declaration of variables reduces coding errors.

    • @tonyennis1787
      @tonyennis1787 2 ปีที่แล้ว

      ding ding ding a winner. Compile-time errors are *much* cheaper than run-time errors.

  • @phyjob
    @phyjob 2 ปีที่แล้ว

    Just a question : isn't gcd(2, 7, 10) = 1, which is not gcd(min (2, 7, 10), max (2, 7, 10))?

  • @ManuelNagler
    @ManuelNagler 2 ปีที่แล้ว +1

    I think Kotlin is quite clean: The gcd function is a 1-liner and I also have to explicitly say "Crash if the list is empty":
    fun gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
    fun findGcd(nums: IntArray) = gcd(nums.minOrNull()!!, nums.maxOrNull()!!)
    Alternatively as extension function, also returning "null" instead of crashing if the list is empty:
    fun Int.gcd(b: Int?): Int? = if (b == 0) this else b?.gcd(this % b)
    fun findGcd(nums: IntArray) = nums.minOrNull()?.gcd(nums.maxOrNull())

    • @nighteule
      @nighteule 2 ปีที่แล้ว

      In the first example, I think you can also make the "gcd" function tail recursive. Doesn't change anything conceptually, but it would make it somewhat faster

  • @goldibollocks
    @goldibollocks 2 ปีที่แล้ว

    Damn, would have loved to see assembly 😁

  • @Erros
    @Erros 2 ปีที่แล้ว

    why wasn't there a running time comparison? I thought that's what the ranking was going to be on

  • @JackDespero
    @JackDespero ปีที่แล้ว +1

    FORTRAN is a very popular language, because there is honestly no better low level language for scientific programming. You can easily get faster code than C which is easier to work with because the concept of arrays and matrices is native to FORTRAN (FORmula TRANslator), while in C is basically a hack. A large amount of very important code in the scientific world is written in FORTRAN.

  • @NoNameAtAll2
    @NoNameAtAll2 2 ปีที่แล้ว

    9:46 doesn't rust have minmax as well?

  • @ceber54
    @ceber54 2 ปีที่แล้ว

    In Julia you can avoid the ellipsis using the functions minimum and maximum for arrays. So the solution is more readable
    function find_gcd(nums)
    gcd(minimum(nums), maximum(nums))
    end

    • @ceber54
      @ceber54 2 ปีที่แล้ว +2

      Now, there are another option to use something equivalent to minmax, using the function extrema, so the solution looks like
      fing_gcd(nums) = gcd(extrema(nums)...)
      but now we can't avoid an ellipsis, but only if we override the function gcd to accept arrays, something that is easy to do in Julia.

  • @segmentkings
    @segmentkings 2 ปีที่แล้ว

    On the first watch I missed the definition of the problem. The problem's title is "1979. Find Greatest Common Dividor of Array" - And I took it.
    It does not say "GCD of the min and max values in an array."
    I was thinking about it for quite awhile, then found it at 1:49. I know, I know..

  • @jongeduard
    @jongeduard 2 ปีที่แล้ว +1

    // Here is our C# version: With static local functions using expression syntax.
    static int FindGcd(int[] nums) => Gcd(nums.Aggregate((prevNum, num) => Math.Min(prevNum, num)), nums.Aggregate((prevNum, num) => Math.Max(prevNum, num)));
    // Self-written Gcd function, but very short and simple:
    static int Gcd(int a, int b) => b == 0 ? a : Gcd(b, a % b);

  • @Scoopta
    @Scoopta 4 หลายเดือนก่อน +1

    I don't program in array languages but from what I've seen I think I'd pick J over the rest because of the ascii syntax.

  • @PanMaciek
    @PanMaciek 2 ปีที่แล้ว +2

    [7:49] julia also has minmax function it's called extrema

    • @b2gills
      @b2gills 2 ปีที่แล้ว +1

      So too does Raku, only its spelled more guessably as minmax.

  • @ZenoDovahkiin
    @ZenoDovahkiin 2 ปีที่แล้ว +1

    I'm part sad that 1st place wasn't Prolog, but also glad that D got in.

  • @VamoAComeLaPapa
    @VamoAComeLaPapa 2 ปีที่แล้ว +1

    C++ solution is better that the other because the number of comparisons:
    - C++: ceil(3/2 * n) - 2
    - The others: 2n - 2
    Thanks to Ira Pohl's algorithm

  • @grantwilliams630
    @grantwilliams630 2 ปีที่แล้ว

    Fortran is nice to work with for array or matrix operations

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b 2 ปีที่แล้ว

    Hoped to see a solution in COBOL

  • @jawad9757
    @jawad9757 2 ปีที่แล้ว

    Assuming you're using vscode, what theme is this?

  • @Chalisque
    @Chalisque 2 ปีที่แล้ว

    I like the brevity of the APL solution, but would rather a semantically equivalent language where instead of symbols we have words, thus something like findGCD := max reduce gcd min reduce -- then you need to sort out binding and preference, and end up with something like the Haskell solution.

  • @maheerali531
    @maheerali531 2 ปีที่แล้ว +1

    Why no javascript?

  • @holthuizenoemoet591
    @holthuizenoemoet591 2 ปีที่แล้ว

    This video introduces me to Dlang. Will use d to make something with raylib

  • @MaxHaydenChiz
    @MaxHaydenChiz 2 ปีที่แล้ว

    Is the reason you always leave out OCaml because the windows support isn't all that good yet? Are you going to start including it once it becomes a one-click install thing?
    I think when people tell you they think you'll like fortran, they have in mind that you can do a lot of array based stuff natively. But as you saw, the "problem" with the language is that it's so focused on optimization that it assumes you already have an algorithm that's easy to type in and is known to work and that what you need from Fortran is the ability to specify a lot of things to the compiler and run-time that let them make all kinds of special case assumptions to eak out as much performance as possible. I suppose that's a fine goal for a language to have. But it's very niche to say the least.

  • @billpeiman8973
    @billpeiman8973 2 ปีที่แล้ว

    Go Forth, young man.

  • @Chalisque
    @Chalisque 2 ปีที่แล้ว

    Decoding the smalltalk version:
    self corresponds to the array
    self min -- asks self for its minimum, returning a number
    self min gcd: ... -- takes the result of self min and sends it the gcd: message
    self max -- sends the max message to self
    gcd: self max -- this is the message send to self min
    in a more conventional OO language it would look like
    self.min.gcd(self.max)
    which looks remarkably like the Ruby version.
    Importantly, gcd: is _not_ any kind of infix operator in Smalltalk.