+201223538180

neoweb4u|Web site Developer I Advertising I Social Media Advertising I Content material Creators I Branding Creators I Administration I System Answer|1 Downside, 16 Programming Languages (C++ vs Rust vs Haskell vs Python vs APL…)

neoweb4u|Web site Developer I Advertising I Social Media Advertising I Content material Creators I Branding Creators I Administration I System Answer|1 Downside, 16 Programming Languages (C++ vs Rust vs Haskell vs Python vs APL…)

Neoweb4u


Neoweb4u|A video looking at 16 programming language options (C++, Rust, D, Clojure, Ruby, Elixir, Raku [Perl 6], Haskell, Racket, Julia, Python, APL, J, BQN, …

supply

40 thoughts on “neoweb4u|Web site Developer I Advertising I Social Media Advertising I Content material Creators I Branding Creators I Administration I System Answer|1 Downside, 16 Programming Languages (C++ vs Rust vs Haskell vs Python vs APL…)

  1. 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).

  2. Some people in this comment section have asked for a COBOL version, so I made one:

    000001 IDENTIFICATION DIVISION.

    000002 PROGRAM-ID. GCD.

    000003 DATA DIVISION.

    000004 WORKING-STORAGE SECTION.

    000005 01 X PIC 9999999.

    000006 01 Y PIC 9999999.

    000007 01 G PIC 9999999.

    000008 01 U PIC 9999999.

    000009 01 MAX PIC 99.

    000010 01 MIN PIC 99.

    000011 01 NUMS VALUE "1223037865".

    000012 02 ELEM OCCURS 10 TIMES PIC 9.

    000013 PROCEDURE DIVISION.

    000014 MOVE FUNCTION MAX(ELEM(1),ELEM(2),ELEM(3),ELEM(4),ELEM(5),ELEM(6),ELEM(7),ELEM(8),ELEM(9),ELEM(10)) TO X

    000015 DISPLAY X

    000016 MOVE FUNCTION MIN(ELEM(1),ELEM(2),ELEM(3),ELEM(4),ELEM(5),ELEM(6),ELEM(7),ELEM(8),ELEM(9),ELEM(10)) TO Y

    000017 DISPLAY Y

    000018 PERFORM GCD.

    000019 DISPLAY "GCD = " G.

    000020 EXIT PROGRAM.

    000021 CALCULATION-SECTION.

    000022 GCD.

    000023 MOVE 0 TO G.

    000024 IF X <= 0 THEN COMPUTE X = -X.

    000025 IF Y <= 0 THEN COMPUTE Y = -Y.

    000026 MOVE Y TO G

    000027 PERFORM UNTIL X = 0

    000028 MOVE X TO G

    000029 DIVIDE Y BY X GIVING U REMAINDER X

    000030 MOVE G TO Y

    000031 END-PERFORM.

    000032 EXIT-GCD.

    000033 EXIT.

    000034

    (the numbers are only required when using IBM mainframes – the length is barely adjustable, reading the code it should be obvious why)

  3. Dart (If Java was created in this decade)

    int findGcd(List<int> nums) {

    // Sort ascending

    nums.sort();

    final first = nums.first;
    final last = nums.last;

    return first.gcd(last);

    }

  4. 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.

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

  6. D and Ruby were by far the best and most elegant. BQN is an ugly mess

  7. 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?)

  8. Maybe since so many of the non-array languages that have array libraries (like Matlab, NumPy, etc.) use the Fortran libraries BLAS and LAPACK in the background, people wanted to see a comparison of array programming with APL & Co. vs Fortran. (Just a guess).

  9. in c# i would write somthing like this:

    static Func<int, int, int> gcd = (a, b) => b == 0 ? a : gcd(b, a % b);

    static Func<List<int>, int> findGCD = nums => gcd(nums.Min(), nums.Max());

    Or wrap bigint gcd:

    static Func<List<int>,int> findGCDFromBigInt = nums => (int)BigInteger.GreatestCommonDivisor(nums.Min(), nums.Max());

  10. There is a min_max function in elixir:

    def find_gcd(nums) do
    nums |> Enum.min_max() |> fn {min, max} -> Integer.gcd(min, max) end.()
    end

  11. This is not correct though. [2,4,5,6,7,10]'s GCD is not 2, it's 1. You have to calculate all denominators, and intercept all, which will give you an array, and then you use a max function.

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

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

  14. 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?

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

  16. No GCD in Fortran or other languages? I suppose one can reuse the explanation given for the BQN. About Fortran, you don't really need a module: you can put functions and procedures in "contains":
    program whatever
    !…. the program using gcd…
    contains
    function gcd(m, n) result (answer)
    ! …
    end function gcd
    end program whatever

    and of course … better using always "==" rather than mixing the old .eq. with ==

  17. In Rust you would usually not pass in a Vec<i32> but rather &[i32]. Also it is better to not panic and instead return an Option<i32>, leaving the choice of panicking to the caller:

    fn find_gcd(numbers: &[i32]) -> Option<i32> {
    numbers
    .iter()
    .max()
    .and_then(|&max| numbers.iter().min().map(|&min| num::integer::gcd(min, max)))
    }

    Or with match instead:
    fn find_gcd(numbers: &[i32]) -> Option<i32> {
    match numbers.iter().max() {
    None => None,
    Some(&max) => match numbers.iter().min() {
    None => None,
    Some(&min) => Some(num::integer::gcd(min, max)),
    },
    }
    }

    I'm kind of sad that rust doesn't have gcd in its standard library and an external crate is required.

  18. I was floored to see that although there is an obvious special case in this problem where the program will crash, of 16 languages, only one (Rust) actually acknowledged it. Error handling is a common point of divergence in programming languages so I was hoping that the video would address it but it seems like he didn't even notice and just thought that "iter().max().unwrap()" is a weird way to spell "max". (Note that Elm used "Enum.max" which makes me think that it doesn't actually crash on an empty list and instead returns the GCD of 0 and the maximum integer value, but this is kind of nonsense and the problem statement should really have clarified what the right answer is here.)

  19. awesome vid. :). ruby has implicit returns, and a more concise would be something like

    # ruby 2.x
    def find_gcd(nums)
    nums.minmax.reduce(&:gcd)
    end

    # ruby 3.x (single line)
    def find_gcd(nums) = nums.minmax.reduce(&:gcd)

  20. Nobody loves Fortran. Sadistic developers just love making other people write solutions in it.

  21. Well for the FORTRAN part, when using functions instead of subroutines, which don't require an interface, you'll have to put an interface block in the variable declaration part. Its like doing a forward declaration of a CALLBACK in C. I modified it a bit and put a little code together that you can test:

    PROGRAM MAIN

    IMPLICIT NONE

    INTEGER :: num_vals

    INTEGER :: gcd_result

    INTEGER :: alloc_stat

    INTEGER :: i

    INTEGER, DIMENSION(:), ALLOCATABLE :: vals

    CHARACTER(LEN = 32) :: val_in

    INTERFACE

    FUNCTION FIND_GCD( nums, numsSize ) RESULT( res )

    INTEGER , INTENT(IN) :: numsSize

    INTEGER, DIMENSION(numsSize), INTENT(IN) :: nums

    INTEGER :: res

    END FUNCTION

    END INTERFACE

    num_vals = IARGC()

    IF( num_vals == 0 ) STOP "No arguments were given…"

    ALLOCATE( vals(num_vals), STAT = alloc_stat )

    IF( alloc_stat /= 0 ) STOP "ERROR: Allocation of value array failed…"

    DO i = 1, num_vals

    CALL GETARG( i, val_in )

    READ( val_in, "(I32)" ) vals(i)

    ENDDO

    WRITE( *, * ) vals(:)

    WRITE( *, * ) "Find gcd: ", FIND_GCD( vals, num_vals )

    END PROGRAM

    FUNCTION GCD( m, n ) RESULT( answer )

    IMPLICIT NONE

    INTEGER, INTENT(IN) :: m, n

    INTEGER :: answer, irest, ifirst

    ifirst = IABS( m )

    answer = IABS( n )

    IF( answer == 0 ) THEN

    answer = ifirst

    ELSE

    DO

    irest = MOD( ifirst, answer )

    IF( irest == 0 ) EXIT

    ifirst = answer

    answer = irest

    ENDDO

    answer = IABS( answer )

    ENDIF

    RETURN

    END FUNCTION

    FUNCTION FIND_GCD( nums, numsSize ) RESULT( res )

    IMPLICIT NONE

    INTEGER , INTENT(IN) :: numsSize

    INTEGER, DIMENSION(numsSize) , INTENT(IN) :: nums

    INTEGER :: res

    INTERFACE

    FUNCTION GCD( m, n ) RESULT( answer )

    INTEGER, INTENT(IN) :: m, n

    INTEGER :: answer

    END FUNCTION

    END INTERFACE

    res = GCD( MINVAL( nums ), MAXVAL( nums ) )

    RETURN

    END FUNCTION

  22. 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<T: Iterator<Item=U>, U: Integer + Clone>(nums: T) -> Option<U> {
    let (min, max) = nums.minmax().into_option()?;
    Some(max.gcd(&min))
    }

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

  24. I don't think Ada would have a hope to reach top 16!

  25. I'm confused, weren't you supposed to reduce through the list? If you pass [4,5,6], your algorithm is going to return 2, when the GCD is 1.

    You're meant to reduce the list using the GCD functiin instead.

  26. 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

  27. Haskell is basically uncompressed J

  28. 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<int> nums) {
    const auto [min, max] = std::ranges::minmax(nums);
    return std::gcd(min, max);
    }

  29. 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.

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

  31. always skipping c# which sucks

  32. Clojure has the same GCD function as Java. You just use it. For that matter so do Scala and Kotlin. I think you probably just have a gap in your understanding of JVM languages

    (defn find-gcd [nums]
    (.gcd (BigInteger/valueOf (apply min nums))
    (BigInteger/valueOf (apply max nums))))

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

  34. Hold up!! Did u just miss to add the greatest programming language to ever exist!? Where is JavaScript, node.js!! It's sad to see that even after much improvement in recent years people are still not giving JS the respect it deserves. Despite JS completely destroying many of the languages covered in the video in terms of popularity, support and community. For those saying that JS doesn't have included GCD i tell you that there are some very good libraries out there that add support such as math.js

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

  36. Its too lazy to exclude languages without builtin gcd function. You just compare call syntax.

  37. title: 1 prob, 16 syntax comparison

  38. I see no issue with the Fortran solution. Functions and subroutines in Fortran look and feel like pieces of code you would write in a program block. In a way, program blocks are more complicated (or simpler, depending on how you view it) subroutines. Some may say it doesn't look nice. I beg to differ, but that's a valid criticism nonetheless. I counter that the feel of writing code in Fortran is more important than how it looks.

    You mentioned interfaces, but there's no need for an interface when you're declaring two functions in a program block. Just use a contains block. If I'm guessing correctly, interfaces were being used in a separate module? Again, no need.

    I think the nature of the problem is why the Fortran solution fails to live up to the other languages. In most of the other solutions, it was one or two lines including the function declaration. For huge pieces of complex code, as Fortran is often good for, the difference of the boilerplate declarations is negligible.

  39. 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.

Leave a Reply