So happy to see you on ocaml, because my favorite Lang is FSharp and ocaml was an inspiration for Don Syme for creating FSharp. =) type inference is a Godsend. Simple, concise, clear code with so little boilerplate to get real things done. So awesome.
@teej_dv2 жыл бұрын
F# does seem pretty cool
@WillEhrendreich2 жыл бұрын
@@teej_dv it really is. Like I legitimately feel spoiled by it. Also, trying to wrap my mind around Lua after fsharp was.. Quite a left turn. Lol. I think I am starting to get it a little more, but there's so much of a mindset shift.
@goosechaser2 жыл бұрын
Am also doing some of the challenges in ocaml, cool to see you are too!
@architbhonsle73562 жыл бұрын
For anyone having trouble understanding what's going on here, "list" is a linked list (I think) and "::" allows you to pluck out the first element of the linked list. At least that's what I think is going on. I have no idea of OCaml works but this seems to make sense.
@teej_dv2 жыл бұрын
that's correct, i will expand on this tomorrow I think!
@AWatProduction2 жыл бұрын
To expand a bit, the :: operator is an infix cons operator. It does not itself allow you to pluck out the first element, but instead it adds some element as the head of a new linked list. The real power now is the pattern matching, which allows you to pluck out the first element (destructure the pattern!), but you could even continue and pluck out any number of elements from the beginning of the list, such as: first_element :: second_element :: third_element :: tail. This combined with guards gives a lot of possibilities.
@abdellahcodes2 жыл бұрын
Nice video! Curious about the syntax highlighting for a single line vs the whole file, is that done at the neovim level or whole editing the video?
@spaghettispaghetto2 жыл бұрын
Great vídeo, I've never tried Ocaml before and this gives me a strong grasp of it. Bye the way, I'm curious what's the app you're using as a whiteboard? Looks neat.
@JakobKenda Жыл бұрын
I feel like learning Rust really helped me with understanding this video.I watched it when it came out and didn't understand a thing but now I think I do because Rust is half functional. It's the `C++ -> Rust -> OCaml` pipeline for me.
@cyprienh21922 жыл бұрын
I study in France, ocaml is the language taught in schools (with C)
@marcoradocchia34612 жыл бұрын
Beautiful video! Just one curiosity: suppose the second part of the problem asked to find the top n values, with n arbitrarily large (but meaningfully smaller than the lenght of the list). Is the method you used (and which I really enjoyed) scalable in a sense that does not require you to write all the n cases? Also I'm wondering: as n approaches the lenght of the list does this just become a sorting algorithm? P.S.: my questions might be dumb... if so, I'm sorry but I'm not an expert in algorithms, although I really enjoy the subject.
@alexscriba6075 Жыл бұрын
I believe since it is a tuple, you would have to rewrite it for every case (since tuples have fixes size and you are hard coding the insertion into each spot). You could probably use a list to keep track of your biggest n numbers and then insert at the relevant index. But that would probably have a complexity of of something like O(nk) where k is the length of the list of max numbers. For the second part, I would imagine if n is close to the length of the original list it would indeed be similar to a sorting algorithm. I think with the method I mentioned above it would be similar to insertion sort.
@pinkorcyanbutlong56512 жыл бұрын
this video appeared weirdly in time with when I just started learning OCaml
@jrmoulton2 жыл бұрын
Haha great to have the interaction with flip!
@Zzznmop2 жыл бұрын
Teej got that big big energy right now. Love to see it
@cattohappy92632 жыл бұрын
I could just sit there and even watch TJ talking about dolphin's sexuality and I would enjoy it as well. Jokes aside, recently I took a Programming Language class which also teaches Ocaml, but even though it is beautiful the standard library felt lacking to me, i.e. I couldn't find any "standard" way to read a file or iterate through its lines, I had to write it on my own, or the string library is a bit hard to work with, and I had to convert it to List of characters most of the times. Probably I was and still missing something about Ocaml and Functional Programming in general, and online I couldn't find any good resources apart from some articles from realworldocaml and Michael Ryan Clarkson's fantastic videos, but compared to F# I really prefer the latter as dev experience.
@dimensionaldot2 жыл бұрын
Just left a long comment with some OCaml tips to make the code you wrote a bit more idiomatic. Seems to have gotten deleted (maybe because I included a link?). Hopefully you can revive it because I'd really like to not type all that out again, but if you can't please let me know
@teej_dv2 жыл бұрын
Hmm, I'm looking but can't seem to find it. I searched several different ways in the app for it. Maybe you could make a gist and link it here or send me a DM on twitter? I'd love to see your thoughts. Sorry yt deleted your comment :/
@dimensionaldot2 жыл бұрын
@@teej_dv No worries! I reconstructed it from memory with the link omitted so hopefully this goes through. Please let me know if you have any question. Original Message: A few notes from someone who recently had/got to write a cross-compiler in OCaml: 1. A slightly more idiomatic way to write the third arm of the outer match in your 'group' function is to write something like: | cals :: rest -> let new_result = match result with | [] -> [ int_of_string cals ] | hd :: tail -> (hd + int_of_string cals) :: tail) in group rest new_result (Note the in at the end of the second to last line, also some parens might be needed around the nested match still but I omitted them for clarity) By doing this you have separated the calculation and the passing of the value of new_result. This is cleaner and better aligns with Ocaml's rpgramming guideline "Naming complex arguments" (details on OCaml site > docs > guidelines). 2. Often you'll run into the situation where a recursive function always needs a certain value to be passed in on it's inital call. The best way to handle this is to wrap the function in question in a new function which calls the old function with the default arugments applied. For example your 'group' function would be rewritten: let group input = let rec group_helper input result = (* original code for group *) in group_helper input [] (* then later just write *) group some_input This has two main advantages. The first is that if down the line you were to change the implementation of group to need a different default value (other than []) you would only need to change it in this one spot instead of every line of your code where you called group. The second advantage is that it hides this input from the public api, meaning that someone can't inadvertently call it with the wrong value. Note that points (1) and (2) would be even more impactful for your 'max3' function as that has an even larger match statement being passed as an argument and has three arguments with default values instead of 1. 3. A more idiomatic way to write the 'max_of_list' function would be: let max_of_list input = List.fold_left (fun a x -> max a x) 0 input Here 'fold_left' is taking three parameters: the first is an anonymous function which takes the accumulated value (a) and value in the list we are currently looking at (x) and return the greater of the two; the second is the initial value for the accumulator (0 in this case because all values are positive); and the list to fold (input). 4. Instead of writing `let () = print...` it is preferred to write `let _ = print...`. While print calls (in general calls to any function executed solely for it's side effects) do return the unit value (denoted ()), writing an underscore is preferred as it makes clear you wish to disregard the value. Finally just noting that your implementation of 'max3' would be even faster than you might think because (as far as I know) List.sort is not tail-recursive and so spends time managing the stack, whereas your code *is* tail-recursive and so will get compiled into a very fast loop.
@dimensionaldot2 жыл бұрын
If you wanted to rely more on list operations, a solution like this comes to mind, which approach is better is probably a matter of preference but this one does avoid the need for the nested match by initially partitioning the input into a list of lists (where each list represents an elf's snack stash). It also does the int conversions after the fact to cleanup the code of 'find_groups' a bit (but again, preference). It also causes a compiler warning on the line where we deconstruct out as we don't cover the case where out = [], but we know this case can't occur. let find_groups list = let rec helper list out = match list with | [] -> out | "" :: tl -> helper tl ([] :: out) | hd :: tl -> ( let out_hd :: out_tl = out in helper tl ((hd :: out_hd) :: out_tl) ) in helper list [[]] let max_of_list list = List.fold_left (fun a x -> max a x) 0 list (* input is a list of the lines in the input file *) let answer = let groups = find_groups input in let int_groups = List.map (List.map int_of_string) groups in let sums = List.map (List.fold_left (+) 0) int_groups in max_of_list sums (* or alternatively, you could combine the type conversions with the summation like so. I prefer the former for cleanness if you aren't trying to optimize (not sure if the compiler can do this level of optimization) *) let answer = let groups = find_groups input in let sums = List.map (List.fold_left (fun a x -> a + (int_of_string x)) 0) groups in max_of_list sums
@teej_dv2 жыл бұрын
Reading these now!! thanks a bunch for taking the time. Super helpful!
@dimensionaldot2 жыл бұрын
@@teej_dv no problem, glad it was helpful :)
@nachiketkanore2 жыл бұрын
What tools do you use to write on screen like scratchpad?
@notAGreatGamer12 жыл бұрын
How did you get the code to highlight selectively?
@thomaspsteven2 жыл бұрын
Probably using the twilight neovim plugin by Folke.
@teej_dv2 жыл бұрын
correct
@billeterk2 жыл бұрын
Very reminiscent of my uni course (‘96). We started with Miranda.
@anarchymatt2 жыл бұрын
we functional boys!
@jfqlkd2 жыл бұрын
What is the program you use to make the sketches? Also ocaml just looks like learnign programming from scratch to me
@fredfred50222 жыл бұрын
You can write max_of_list = List.fold_left max 0
@Danielo5152 жыл бұрын
Can believe you use a proper keyboard and a proper language. I'm impressed
@simondebevoise32612 жыл бұрын
one nice thing that you can do to avoid lost of nested parens is to use the pipe operator, like so: let () = group result [] |> max_of_list (* if you rewrote max of list to take one arg *) |> string_of_int |> print_endline ;;
@tsunningwah3471 Жыл бұрын
ki
@markmcdonnell2 жыл бұрын
Anyone know the colorscheme used? Also the plugin for inactive code segments? Thanks
@Kartoflaszman2 жыл бұрын
inactive code segments is "folke/twilight.nvim" not sure about the colorscheme but it might be "tjdevries/gruvbuddy.nvim"
@alekseiabakumkin95572 жыл бұрын
This reminds me of times when I played with LISP :)
@nickskywalker25682 жыл бұрын
OCaml is such a great language!
@gavinvales89282 жыл бұрын
damn ocaml is elegant
@MesheeKnight2 жыл бұрын
wanna see elixir!! but ocaml is cool
@TrickTrickist6 ай бұрын
не на цвяхах, і не постояла - порада, поглянь на це як наче пройшло 5 років, і ти аналізуєш те шо ти переживав і як воно було, і стане в рази легше
@sillybuttons9252 жыл бұрын
lol
@ewrietz2 жыл бұрын
1st
@teej_dv2 жыл бұрын
true
@randomcubestuff34262 жыл бұрын
thank you for the information
@ewrietz2 жыл бұрын
@@randomcubestuff3426 firstly, you’re welcome. Secondly, sounds like someone wishes they were firstly