#dev-general
1 messages ยท Page 481 of 1
hmm
@ could also be used for pattern matching if we're copying taking influence from haskell
https://github.com/haskell/haskell-language-server
hls is this, right?
case x of ->
r@Record(a _ _ ) -> putStrLn (show r ++ a)
yeah ~/.ghcup/env needs to be added
i think it offers to do that for you if you install it with the shell script, but not if you used the aur package
ah
also ghc isn't in path
that will be in /env too
and what do I put there
.
i presume you know how to add a directory to your path
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
.ghcup/env doesn't exist
ah, thanks
oh wait yeah
if you have stack as well
export PATH="$HOME/.local/bin:$PATH"
I have neither yet
download both
my bad, it's env on my machine but it did weirdness
well hold on
it just told me to upgrade ghc, jesus christ
lol
hmm
does vsc work with 9.0.1 yugi?
kali was having some issues with it the other day
although that was on windows
It should
It gives a warning in the main file tho
but that should be fine
downloaded, installing
excellent
[ Warn ] This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.
[ Error ] Unable to find a download for the requested version/distro.```
stack-static is an aur package
idk the exact reason but i think it's because it's kind of 3rd party
okay got them installed
awesome
lemme just add to path
might have done that for you if it's on the aur
you using VSC?
nvim
stack new <Project_name>
it made a bunch of stuff
yeah tbh, you might want to steer clear of the build tools for the absolute basics
kinda overkill if you just want a hello world
maybe just use ghci
yeah
200mb fuuuuuu-
ghci is the jshell to java
lol
after stack new or?
leave that project for now ig
or delete it, whatever. you can just use a single file for now
https://docs.haskellstack.org/en/stable/README/
Further instructions to use stack are here if you're interested
okay so anyway, in FP you often program at a REPL as it's usually more convenient for hacking together stuff
the official repl is ghci
ah I see why it isn't in path
there's no ghci or ghc bin, there are bins with a version
ghci-9.0.1 is a command
ah that's an issue i was having a while ago
there should be or I should alias?
yep probably it
can you do ghcup tui and make sure you've set the versions you have installed
okay ran ghcup set 9.0.1
alright, now it should work
does
awesome
lit
okay so uh
I have a shell thing now
oh my god 9 + 9 works
incredible
sum [1..9]
where are the parentheses
you don't write them
^
sum [1..10000000] is slow
try sum [1,3..11]
in haskell (and other ML style languages) parentheses are to denote precedence, not for function application
well ofc xD
my shell just crashed from doing this
okay it works now
you can probably identify all the parts in that, [1..n] is a list between 1 and n, and sum is a function that... sums a list
36
simple
yeah I see
(10million * (10 million + 1) )/2
does .. only work in the [] thingies?
yeah
those are lists
sum takes a list as input
gauss shit
they're list literals, you can also do stuff like [1, 2, 4, 8]
does .. have a step?
sum :: Num a => [a] -> a
is the type
it can't do that unfortunately, sum has to be generalised for any summable type
or maybe it does do that
F
You can provide the step pattern in the list
idk
probably not
okay now you lost me
dw about that
Thats its type signature
oh oops
fixed
sum :: Num a => [a] -> a
is that a named return value?
no
in java terms that's <A extends Num> A sum (List<A>)
Thats a constraint
but dw too much about that for now
ah
let's keep it simple
so a is a type
No
no?
num is a type constraint, kinda like an interface except more powerful
right
in other words "a can be any type that implements the Num type"
anyway
so
we know how to use functions
time to make a function
double x = x * 2
try this
or that
^
lol
you get used to it
works
and then naturally you can do double 3 etc
yay
awesome
uh so
now define another function
double 3 + 5 does what
that won't compile i don't think
(double 3) + 5
yeah function calling has the highest precedence
although not often
yep
converting?
how dare u
๐
Its a cult here
excuse me, I'm a catholic
also, cool bonus feature - when you're in ghci you can do :t x to find out the type of x
try :t double
I am learning about your culture, not converting
lol
we'll see about that
floats are fractionals?
Theres a distiction in haskell actually
yeah...
haskell has both fractional numbers and floating point numbers
decimal stuff is kinda messy sometimes
pi is floating
my 6.9 is fractional
is fractional so you don't lose precision?
Depends on the type you operate on and the functions you use fefo
it's a bit confusing
anyway, you'll probably know this from rust and kotlin but in haskell, functions are values
what's next
meaning they're no different to any other "variable"
you can pass functions to functions, functions can return functions, etc
right
Fractional is just anything dividable generally I think
is pi not divisible
It can be
confusing stuff
okay what next
Strings
they're pretty similar
exactly the same even
and of course you have Chars too
exactly the same syntax as any other language for those
in other words "'E' is of type Char"
so like.. it's a fraction basically lol it can be represented as a ratio of two numbers
right?
well numbers idk what you can do in haskell but hopefully you get what I'm trying to say
lol
so what do I use when I want to deal with decimals?
generally i think you'd just let the compiler figure it out
Rational?
i guess Floating is the "traditional" way, but im not sure what's conventional tbh
classic native languages
Seems like it also consists of irrationals? not sure tbh
so how would I make a multiline function?
do blocks
good question
But
this is where ghci gets a bit annoying
Warning
you can't do multiple line stuff very well
those are syntax sugar, anything not part of the final result either as a value or as a bind will NOT be evaluated
lol
okay you might wanna switch over to an actual editor now, and make a new file
we'll have a look at do blocks
Minecraft on java 1.16 ๐ถ
Yasss
initializing languageserver.haskell
๐
๐ฅฒ
Ok mockito is just trolling now
Why does it say cglib is not on the classpath when its right damn there
๐ฅฒ
classic
Cannot find any haskell-language-server exe, looked for: haskell-language-server-9.0.1, haskell-language-server-9.0, haskell-language-server
f
I don't have it installed for 9.0.1
did you do ghcup set hls?
๐ฅฒ
ok screw this
ima keep typing while you try and figure it out - i could never get vim working but i also suck at vim so that might be why
the problem is that hls doesn't support ver 9
ah
is there any other framework that can mock with proxies?
Wouldn't happen unit testing Haskell!
I guess I'll just go back to 8.10.4
that's similar to the problem kaliber was having a while ago
ikr
yeah that's probably best
you're not gonna be missing much
okay so, in haskell every function is a single expression. there are no "blocks", just expressions.
however as you might expect this can get a bit annoying, so there's a syntax sugar called "do blocks" that replicate an imperative {} block
okay it loaded in like a second
good enough
Seems like Ktor uses Mockk for it
okay yep works
okay so let's start with the main function actually, you've already seen putStrLn "hello world", but that only evaluated in the repl
yes
like most languages we have a main function
yup
yay I guessed it
what if I want more lines?
Does that work outside kotlin? the 2 kks make me feel like its for kotlin
that's when do blocks come into play
how do I close a do?
try this: ```hs
main = do
putStrLn "hello"
putStrLn "world"
Ah, probably not yeah ๐ฆ
welp
klassik kotlin adding K's everywhere ๐
it's indentation based
ah
๐ฅฒ
Lmao yes, i actually hate that xD
you can technically use braces if you want, it's just not generally done
main = do {
putStrLn "hello";
putStrLn "world";
}
this is also valid
{ haCharBuffer :: IORef (...something...)
, haBuffers :: IORef (...something...)
, haBufferMode :: BufferMode
}```commas before the line??
w- what
Except thats not the convention ๐ฅฒ
Prepare to be horrified
main = do
{ putStrLn "hello"
; putStrLn "world"
; }
the conventions for spacing and things are definitely a little different
yea
yes ๐ฅฒ

but im not sure it can be considered a convention if nobody actually writes it like that
Who created that convention? i need to have a talk with them
They do use that I think
thank fuck
ah
not working
yup
indeed
Anything the derives Show provides a show function
OH MY GOD
Which can "Stringify" it
gradle 7 for fabric mods UJFDSUOJSDNBJLOS
is that ! a part of the type?
putStrLn :: String -> IO () this is the signature of putStrLn - it takes a String, and returns an IO () (which we'll get to in a minute)
what the
show is roughly analogous to toString
works
I removed the parentheses, it doesn't work
to save yourself from parenthesis hell
We have custom operators
Haskell has one defined in the base class to apply an argument
yeah, that's because of precedence. without the parentheses it would be interpreted as putStrLn(show, 3) in C-style function calling
This is for a single argument and so can only be used for the last argument
whereas what we want is putStrLn(show(3))
shows a warning
It simply takes whats on its right, and applys its to the function on the left
tells me to use print 1
indeed
that's kinda verbose so there's print which is a combination of putStrLn and show
brb
how do multiple args work?
i dont think so, this is where it can get a bit confusing
actually maybe
try it
i don't think it will
add(add(1, 2), add(3, 4))```
add x y doesn't compile
you need the body
I have it
oh do I put the add outside of main?
yeah the thing doesn't compile
lemme try parentheses
yeah outside of main
you can nest functions, but that has a slightly different syntax
print $ add (add 1 2) (add 3 4)
that should work
it does
awesome
what kind of chain rule is that lol
weird and confusing
heh
okay
now for the real mind-blow
go into ghci, define add again and then check the type of add
add :: Num a => a -> a -> a
loll
looks very intimidating
it's actually quite simple
I want to kill it
in haskell functions only have 1 parameter
they what
if you have functions with multiple, that's just a function that returns a function
and so on
I know what curry is
currying is the process of applying curry to food?
close enough
anyway, what this funky parameter stuff means is that we don't need to provide all of the parameters to a function
so for example, we can do add 3
oh
which in turn returns another function
so that returns a function we can use later
exactly!
similar to julia
oh does julia do that too?
yeah some functions return a function if you don't supply all params
ah cool
yeah, super common pattern in FP
i was gonna explain where it might be useful but im guessing you already know
julia> ==("69", "69")
true
julia> ==("69")
(::Base.Fix2{typeof(==), String}) (generic function with 1 method)
I have no clue where that could be useful
ah yeah exactly the same thing
okay
well
you're familiar with map and filter right?
hehe
I see
yup
filter(==("69"), arr)
exactly
in julia
in haskell that would be filter (== "69") arr
is equivalent to filter(x -> x == "69", arr)
so almost exactly the same
lol no problem
it's getting late and I haven't showered in 3 days
๐ฅถ
fair enough
if you decide to carry this on feel free to ping me if you have any questions
actually gonna go a bit later
so you told me all about functions and all that fancy stuff
yup
but what about if statements
no statements, only expressions
right
the difference being that an if requires an else
it what
so it can evaluate to some value
because everything in haskell is an expression
and the definition of an expression is something that evaluates to a value
does haskell have no void type?
it does
do functions with 0 params exist?
eh?
because haskell does lazy evaluation
ah
so you can do blah = print 3 and that won't actually print anything until you try and get the value of blah
it is a bit weird
name = value
in main
let test = print 69
```this doesn't work until I access test
yeah
that line alone won't print anything
because it doesn't evaluate until it's forced to
let test = print 69
test
test```this prints twice
it's like a weird ass macro
basically, to keep functions pure, stuff like print don't actually print anything, they just return a value that describes some IO.
so it's returning the same value every time, but the do block is executing the IO twice
print doesn't actually print anything, it returns a value that's sort of like a list of instructions on what IO to do in order to print that value
why is it executing the value?
because the do block assumes you want to execute it
oh is test like a 0 param function now?
kind of
this is quite a tricky concept
but it will make sense
it's probably best not to worry about that for now
for all intents and purposes, it's a 0 param function
lol
ยฏ_(ใ)_/ยฏ
basically, haskell wants every function to be pure, so it doesn't actually do any IO, it just describes the IO to do, and then the compiler bundles that up and does evil wizardry to perform that IO
the language stays pure, but it can still do IO
might as well rename this channel to #intro-to-haskell
Tomorrow at 00:00
im kinda diggin it though
just following along after
makes actually a bit of sense
hey do you know how to do infinite lists BM
yes
what's up with those
wdym
what are they used for
but super cool!
but usually number generating stuff
how do you get all odd numbers
oh I see like a number generator is just an infinite list of all possible numbers generated?
yeah
if you wanted to generate a list of all primes, a naive but functional implementation would be filter isPrime [1..n]
2N+1
[1,3..]
lol
yup
sadly it's not that sophisticated
it can do arithmetic progressions
not much more than that
is that valid haskell
probably valid julia lol
โ means is an element of in set theory
you could do an infinite list of all fibonnacci numbers with some recursion magic
2n is just multiplying n by two lol
but | is just binary or
| means such that
shame
you read that statement as: 2n -1 such that n is an element of all natural numbers
so basically every odd number
main :: IO somethingwat
Ah you've discovered the IO monad
haha monads go brrr
Now we're cooking with gas
I haven't discovered shit, I just googled how print works
gas
Lol
btw, what's haskell used for?
Quite a lot
It's definitely traditionally used for academia
But Facebook uses it for spam detection, GitHub uses it for language parsing
yeah as I said it's really good at expressing set theory and category theory lol
type theory too
It's gaining more adoption
But yes the original use case was definitely just for nerdy professors to experiment with complicated mathematical ideas
Which sounds pretty fun tbh
it's gaining more adoption? isn't it half a century old?
hey im a nerdy normal person, not a professor
python was made in the 90's and it's still gaining more adoption
Nah Haskell came out in 1991 iirc
Or around that time
93 maybe
yea a lot of langs came out early 90's
ML go brrrr
I mean lisp was like 1958 or something
ml is what
Maybe 61
ML is the precursor to Haskell
what does ml stand for
There were quite a few functional languages in the 70s and 80s, until they realised that there were too many languages to learn so they all sat down and made Haskell
That's not a joke
Pretty much what happened
ML was pretty influential afaik
That and Lisp were like
The big 2
Back in the day
how do you read that
awe man what a time to be alive
Not that I'd know
try spelling it out, with a ck instead of a q
hmm
u horny ass
oy
lmao
is it cause I mentioned C++
blyat
it summoned you out of your cave
lol not because of that, no
Ofc
I was laughing about this tbh
monads?
woah have you guys heard of Cyclone
it's like C but they made it harder to fuck yourself
Oh that's gonna take a while to explain
Pretty low bar
yeah
I don't like when they make it hard to fuck yourself
bro go back to writing ASM then
if I want to fuck myself I will do it and nobody will stop me
Damn right
I actually did do some a few days ago
nasm
Okay I am gonna go to bed pretty shortly but I will try and briefly explain the IO monad (or at least the idea behind it)
network assembly I think is what it stands for
Netwide Assembler apparently
close enough
back
how far did you get vr?
in ASM? holy cow
the literal equivalent in c did work
so I was left confused
it didn't error, it just returned
weird stuff
well not returned, ran the whole thing
without error
also debugging assembly is a pain in the ass
especially without libc
Seems like human anatomy
this is what I was talking about earlier where we have an abstraction that describes some IO to do. The main function says "this is a list of the IO I would like to do", and the compiler turns that into evil unsafe code.
This is expressed through the type IO a which basically represents some IO operation that returns an a
So print and putStrLn are IO () because they're an IO operation that returns no meaningful value (() is the void type, known as "unit")
Dont forget Elm ๐
yugi really going back through the message history and commenting
similarly we have other IO functions like getLine (gets a line from standard input), this returns an IO String
Yea
also Wikipedia does not list Elm as an ML boi
Elm is afaik
hmm well it is kind of confusing
yeah influenced
Even haskell was "influenced by"
Its literally the same syntax as haskell
can you print inside another function?
It only lacks custom monads
Yes, but that function has to return an IO value
Elm is actually pure
oh
yeah ML isn't 100% pure
what if I want to return another value?
it allows unsafe stuff
Ofc, Elm isnt a complete ML ripoff
I just meant it shares the same elements haskell does from ML
Example?
or atleast most of it
if I have a function that prints 69 and returns 420
nice
So something like ```hs
funny = do
print 69
return 420
This would have to return an IO Int
IO Int?
combo types!!!!
Because it's an IO operation that eventually returns an Int (420)
what if I don't know how a Future works either ๐ฅฒ
wait can I run any function that doesn't return IO in main?
Haskell itself does not read or write anything, so it needs to compose IO Actions to create the sideeffects
Yes
I can't run add
IO functions can only eb called in IO functions
Except a few cases wher eyou can lift em with transformers
but the general rule stands
That is because you're not doing anything with the result I'm guessing
yugi you might be overcomplicating this a little
yes
๐ฅฒ
Yeah you have to bind it with a let binding, or not call it at all
doesn't binding just not run it at all?
oh snap he's got a point
It will run it if you force it to evaluate
lazy evaluation biting oyu
so say I got this
add x y = x + y
main = do
let poo = add 69 420
print "ha"```
this works fine
but add will never actually be called
Mhm
right
print poo
Everything is evaluted only when it needs to be
and I can't just put poo on the next line, it won't work unless I print it
the thing is, because add is pure you won't actually know that it doesn't get called
there's no noticeable difference
well yes, but I will know
Indeed
sounds like a functor to me ๐
a what now

do you call a functor or is there a fancier word?
is it really
this is why we stay in haskell land
Well you could say "A mapping between 2 categories"
no weird C++ shit
But
Assuming you are sane
And havent started circlejerking
lets just go with function
I would never do that
anyway, Vr the reason you can't just do poo is because of what do blocks compile to
what do do blocks compile to?
main = do
print 3
print 4
This gets translated to ```hs
main = print 3 >> print 4
?
Yeah
It basically takes 2 IO actions and turns them into 1
oh I didn't know you actually knew haskell lol i thought that was a C++ thing
it's like .thenRun with a CompletableFuture or something
what happens to bindings?
they get inlined I believe
So your poo example becomes ```hs
main = print (add 69 420)
wouldn't that call the function multiple times?
what now
yeah a functor is also a thing in C++, although I think it's different
and no I don't know haskell lol
ah nice
We generally don't worry about it, because the compiler can determine whether it's worth caching or not
this kinda what yugi was saying earlier, how you don't need to think about performance much
because the compiler is able to do a lot of the optimisations for you
so can I think of bindings as kind of #define?
they usually act in a similar way yeah
But they might not, as far as I know that's an implementation detail
so, what's a monad?
functor + map, or just flatmap
๐ฑ
uh
It is getting pretty late so I don't think I can explain that now
you mean early
But an oversimplified explanation would be "an abstraction over a value"
LMAO classic
Adios
chao
I just call monad a thing that has flatmap, which is just lazy operations over the wrapped object, plus flattening the object later (if I'm not mistaken here)
Absolutely
The only thing stopping me from talking about Haskell 24/7 is school and "sleep"
Quite unfair imo
okay I just realised I forgot to do something I should've done 3 hours ago
uh oh
no, not 3, 5 hours ago
๐ฅถ
A global mute will also stop you :)
WHAT
why do I have to bring papers physically
I have a phone with a camera
I want to die
cya
gn
same
Oh boy
arguably newer versions are more optimized. then we have better switch expressions, records, sealed classes, the java std lib gets better and better also for every version
new gc
List.of() ๐
lol
Basically everything
CMS yeah boy
ty
yeah lol
Yup, it had for some time, 1.5 added sealed interfaces though
Actually just used it for the first time today
Private Methods in Interfaces
I genuinely don't see the point in this though
me neither
Who cares about you two ๐คท
wait holy shit I just realized how awesome Java 16 will be for plugins
this solves my oldest woe of everyone using JDK 8
so you dont specify which classes can extend that but define them inside the sealed class itself? @ocean quartz
You know what would be awesome
huh?
Valhalla ๐ฅบ
what specifically? or do you just mean the new features in general?
what is there not to understand
i hate how everyone uses old java versions
and this fixes it
tldr for valhalla?
Probably not
oh I misread
You can even define them outside, as long as they are in the same file
oh yeah i mean just everything
Ah nice
ah ok
i am usually very sad that we don't get to use anything cool
but now we get like switch expressions and record classes or whatever
Yea happens when you dont use haskell
i gotta read up on new features babyyy
I came just by reading List<int>
c# being ahead of its time ๐
For Kotlin it means full support for value classes and a few other features I don't remember much
Ic
no its just java being behind its time
nullpointerexception
ew
I'm sure you've read this one before cuz I've shared it before but for a more detailed list of things that whatever Matt shared ๐ https://advancedweb.hu/a-categorized-list-of-all-java-and-jvm-features-since-jdk-8-to-16/
yeah I skimmed it once but it just made me sad cause I thought I would never use them
now read it joyfully 
Why not?
because this is the only reason people will upgrade java versions
have you seen the graph
70% or something of people are still on java 8
I assume you plan to make stuff outside of the minecraft community as well
not with java probably
ah I c
that's what Rust is for ๐
there's really not too much you can do with Java
Did you know that 33 percent of obese men have a low sperm count?
i don't see many projects besides Minecraft stuff written in java
What is this "too much"?
And one of them could be you
bruh
There are lots of applications written in java
lmaoo
such as?
Google it up my guy
wow great point proving
The amount of web servers using Java is insane
moral of the story, I don't see a lot of stuff I'd like to work in written in java
A lot of people using spring