I love these videos where there are multiple languages. You get to see what is kinda the same, and what really has to be different. If it was just one language I would get it less. I think I learn a lot from seeing the difference at work to make sense of both.
your haskell function looks very clean. it uses an extra function declaration and a (.:) operator import, however. here's my attempt at solving with just the haskell prelude. :] leftRightDifference = zipWith ((abs .). (-)) . (tail . scanr (+) 0) (init . scanl (+) 0)
That's ugly... Why in the world would you be against using things outside of the prelude? You know the prelude is universally considered terrible right? People are so weird
That video implicitly exists already inside this one: ua-cam.com/video/8ynsN4nJxzU/v-deo.html and also this one: ua-cam.com/video/UogkQ67d0nY/v-deo.html
Instead of defining the `phi` combinator yourself, you can also look at the `Control.Arrow` (and `Control.Category`) module, which gives rise to the following Haskell solution: ``` ((scanl (+) 0 >>> init) &&& (scanr (+) 0 >>> tail)) >>> uncurry (zipWith (-)) >>> map abs ```
When I'm doing some hard leet code problems, I struggle to find a functional solution, it seems that those problems are created in a way to be solved with dynamic programming. Can you do a video solving some problems tagged hard on leet code or any other site using the functional paradigm?
Hello, this is very interesting. I have been using a Lisp (LispE by Naver) that provides some APL-like instructions and I came up with the following solution: (zipwith (\(x y) (fabs (- x y))) (cons 0 (pop (\\ '+ r))) (consb (cdr (reverse (-\\ '+ r) )) 0)) \\ and -\\ are the scan and back-scan operators and '\' introduces a lambda function... Very similar to your own solutions...
I think they are great for both. BQN is a very young language but there are already a bunch of companies that use APL in production: github.com/interregna/arraylanguage-companies
@@code_report I always get thrown off how many of the companies doing fancy code stuff are in finance, I guess it makes sense since finance companies are likely hiring mathematicians and not just regular software developers
The rust version should be, nums .iter() .copied() .zip(nums .iter() .rev() .copied()) .scan((0, 0), |acc, (l_ele, r_ele) { let ret_val = *acc; *acc = (acc.0 + l_ele, acc.1 +r_ele); ret_val }).map(|(a, b)| a - b) .map(i32::abs) .collect() A lot more verbose but that's because it's a bit different approach
Yeah that's quite cool. But i still prefer the readablity and simplicity of plain C: /*Caller free the result*/ int *solve(const int *array, size_t size) { int *result = malloc(size * sizeof(int)); int *lsum = calloc(size, sizeof(int)); int *rsum = calloc(size, sizeof(int)); for (size_t i = 1; i < size; i++) { lsum[i] = lsum[i - 1] + array[i - 1]; rsum[size - i - 1] = rsum[size - i] + array[size - i]; } for (size_t i = 0; i < size; i++) result[i] = abs(lsum[i] - rsum[i]); free(lsum); free(rsum); return result; } No need to know about any weird concept or some obsure std feature. plain, readable procedural code.
@@computer-love I didn't say it wasn't intuitive. I mean't that if you need to use the specific language to understand what does the symbols actually mean and implies. The power (IMO) of procedural is that you can follow the execution as it happen. This lead to more obvious and easy to understand code. much cleaner than APL or BQN (no, having a bunch of cryptic characters isn't by any mean clear). If you learned any language of the C family (java, c++,... and any language which support procedural pattern) you can easily reason and understand what the code actually mean. In small, easy problem like this one both are good, but i have my doubt about the readability of a big BQN project. Don't get me wrong, i really some feature of functional language (i love the Maybe / Error / Option monad) I just think using every feature of the language makes code less pretty and easy to follow.
Haha this is the other extreme :) I also don't know BQN, but I have played around with some haskell in Uni. I really liked these list operations like fold, map, filter. I think for me the most readable approach would be something like Python Numpy or C# Linq, which is from my understanding close to the haskell solution
the only reason that feels simple is because we're used to C. i tutor and the concepts in your code are not remotely simple for most students. the most popular languages derive from procedural or C style programming, so of course that's what you're comfortable reading. as for following the execution, again, that's a function of familiarity with the language. one can follow the BQN code just fine, not to mention taking it apart piece by piece to watch literal data mutation is trivial.
liftA2 in Haskell (in Control.Applicative module) is a builtin phi combinator
Enough with the trivial examples! Now let's see a 3D game engine in BQN. Can you do it in 25 lines of code or less?
I'd settle for a useful commandline tool.
If I had to guess, the part that computes game state probably could be, if you omit the part that does I/O (controls, graphics, audio)
@@derelbenkoenig so we just need like C bindings and we are ready to go
CBQN has some basic C bindings available.
I’ve been working on an ASCII-based array language called Noda. Here’s how I’d solve it:
*abs(>>nums(+) - > and
I love these videos where there are multiple languages. You get to see what is kinda the same, and what really has to be different. If it was just one language I would get it less. I think I learn a lot from seeing the difference at work to make sense of both.
your haskell function looks very clean. it uses an extra function declaration and a (.:) operator import, however. here's my attempt at solving with just the haskell prelude. :]
leftRightDifference = zipWith ((abs .). (-)) . (tail . scanr (+) 0) (init . scanl (+) 0)
Was hoping to see the applicative instance of reader (S combinator) come up! Nice
That's ugly... Why in the world would you be against using things outside of the prelude? You know the prelude is universally considered terrible right? People are so weird
I love it. Can you make a video comparing the differences between BQN and APL? They seem quite similar, but I wonder why they say BQN is better
That video implicitly exists already inside this one: ua-cam.com/video/8ynsN4nJxzU/v-deo.html and also this one: ua-cam.com/video/UogkQ67d0nY/v-deo.html
Instead of defining the `phi` combinator yourself, you can also look at the `Control.Arrow` (and `Control.Category`) module, which gives rise to the following Haskell solution:
```
((scanl (+) 0 >>> init) &&& (scanr (+) 0 >>> tail)) >>> uncurry (zipWith (-)) >>> map abs
```
That BQN had shift primitives and the Under operator did help. Something for my SugarBQN namespace.
When I'm doing some hard leet code problems, I struggle to find a functional solution, it seems that those problems are created in a way to be solved with dynamic programming. Can you do a video solving some problems tagged hard on leet code or any other site using the functional paradigm?
Hello, this is very interesting. I have been using a Lisp (LispE by Naver) that provides some APL-like instructions and I came up with the following solution:
(zipwith (\(x y) (fabs (- x y))) (cons 0 (pop (\\ '+ r))) (consb (cdr (reverse (-\\ '+ r) )) 0))
\\ and -\\ are the scan and back-scan operators and '\' introduces a lambda function... Very similar to your own solutions...
Can you please add common lisp sbcl to the problems videos solutions
Do you think that languages like BQN and APL should be used in the making of commercial products or just as a fun exercise?
I think they are great for both. BQN is a very young language but there are already a bunch of companies that use APL in production: github.com/interregna/arraylanguage-companies
@@code_report I always get thrown off how many of the companies doing fancy code stuff are in finance, I guess it makes sense since finance companies are likely hiring mathematicians and not just regular software developers
has BQN replaced APL as your favorite language?
Yes.
@@code_report what about J?
Can we get maintainable code in BQN? I'm talking a project with a shelf life of more than 6-9 months.
Maybe
you are a great explainer
Would be nice to see C++ and Rust solutions
Here is a Rust solution using a array library in Rust (but unfortunately it's not public atm): pastebin.pl/view/5caf93b6
The rust version should be,
nums
.iter()
.copied()
.zip(nums
.iter()
.rev()
.copied())
.scan((0, 0), |acc, (l_ele, r_ele) {
let ret_val = *acc;
*acc = (acc.0 + l_ele, acc.1 +r_ele);
ret_val
}).map(|(a, b)| a - b)
.map(i32::abs)
.collect()
A lot more verbose but that's because it's a bit different approach
I would assume Ctrl+L clears the screen in GHCi. Also yeah structural Under is so cool
Thanks! I think knew that at one point but forgot. And agree, under is awesome!
When you type :! In ghci you can do shell commands. So :!clear will clear the screen
Beautiful
Control.Arrow might come handy with uncurry
(&&&) :: (a -> b) -> (a -> c) -> (a -> (b,c))
`uncurry` is in the Prelude i think
@@ponirvea yes (&&&) is not however
How do you guys program in APL? Do you have a custom keyboard that contains all apl symbols? Do you just have a tab open with ascii tables?
Most editors you type ` (backtick) and then a key. And you very quickly memorize the symbols. `i is iota. You can try here: tryapl.org/
Why use x rated videos when you can read BQN solutions?
didn't take you long to switch alleigence away from APL :P
haha, APL is still my second favorite languages. BQN has more combinators and sort primitives though 😂
I thought the B combinator was
B f g x y = f x (g y)
Are there different naming schemes for them?
No, that is the D combinator. See here: combinatorylogic.com/table.html
@@code_report Oh, yeah. I was thinking of B1 the Blackbird, but I was also wrong there too
Yeah that's quite cool. But i still prefer the readablity and simplicity of plain C:
/*Caller free the result*/
int *solve(const int *array, size_t size) {
int *result = malloc(size * sizeof(int));
int *lsum = calloc(size, sizeof(int));
int *rsum = calloc(size, sizeof(int));
for (size_t i = 1; i < size; i++) {
lsum[i] = lsum[i - 1] + array[i - 1];
rsum[size - i - 1] = rsum[size - i] + array[size - i];
}
for (size_t i = 0; i < size; i++)
result[i] = abs(lsum[i] - rsum[i]);
free(lsum);
free(rsum);
return result;
}
No need to know about any weird concept or some obsure std feature. plain, readable procedural code.
one person's "weird concept" is another person's "intuitive pattern"
@@computer-love I didn't say it wasn't intuitive. I mean't that if you need to use the specific language to understand what does the symbols actually mean and implies.
The power (IMO) of procedural is that you can follow the execution as it happen. This lead to more obvious and easy to understand code. much cleaner than APL or BQN
(no, having a bunch of cryptic characters isn't by any mean clear).
If you learned any language of the C family (java, c++,... and any language which support procedural pattern) you can easily reason and understand what the code actually mean. In small, easy problem like this one both are good, but i have my doubt about the readability of a big BQN project.
Don't get me wrong, i really some feature of functional language (i love the Maybe / Error / Option monad) I just think using every feature of the language makes code less pretty and easy to follow.
Haha this is the other extreme :) I also don't know BQN, but I have played around with some haskell in Uni. I really liked these list operations like fold, map, filter. I think for me the most readable approach would be something like Python Numpy or C# Linq, which is from my understanding close to the haskell solution
the only reason that feels simple is because we're used to C. i tutor and the concepts in your code are not remotely simple for most students.
the most popular languages derive from procedural or C style programming, so of course that's what you're comfortable reading. as for following the execution, again, that's a function of familiarity with the language. one can follow the BQN code just fine, not to mention taking it apart piece by piece to watch literal data mutation is trivial.
Which city which conference ? If its close I might attend
LambdaDays in Krakow: www.lambdadays.org/lambdadays2023
Cool
lol @ 3 glyphs being 'overly verbose'🤣
[ abs (l - r) | l
BQN FTW
I got rank 379 in this contest
Nice!
crude ngn/k solution (as a function) before watching: t:{a:(+\x)-|+\|x;a*1 -1a
what
Love it! A great video to pause and ponder. This was my attempt in BQN +`∘»{|𝔽-𝔽⌾⌽}
In fact it's enough to do: |+`⌾⌽-+` The shifts are not needed!