Programming Crystal Book Club

Maybe write a #community:journals for that as well Mafinar? I am sure many people will find it interesting :smiley:

1 Like

Yes of course I will. This is not the first time I attempted to learn an ML. I tried with OCaml, F# and even ReasonML numerous times and then backed out for some reason. Especially I went far with F# then all the .NET specific terms came up and I backed out. I love the language though.

I hope with a #community:journals it would work for me. I know I learned Crystal and completed a book from it.

2 Likes

There you go: My OCaml Journal

Had to switch to OCaml at the last minute, I did not like ReasonML documentation and the fact it took my a long time to get VSCode to work.

2 Likes

It has a lot of features, but it’s not pluggable. You can add backends to go through sure but if you are wanting ‘more’ capabilities then you can’t really do that in the existing framework. This is why I like how Rust’s works, it just supplies some basic ‘points’ that a logger can plug in to, then it can do whatever it wants, it’s significantly lower level though, but much more powerful.

For example, not only can you log text messages with warn!("blah") or whatever, which does also give a huge variety of information about its calling context (which, of course, the logger can do more to) but you can also add more information like warn!("blah", user_id=user.id, some_more=metadata) but you can even ‘span’ logs across more than just a single point, so you could do, for example, let _ = warn_span!("blah", ...) and it will be held in that entire scope, giving wrapping other logs that happen during it (like deeper in the callstack), can give timing details if the logger so wants it (or no cost if it doesn’t), etc… It is pluggable even with profilers, which makes timing code easy as well, you can do that in Elixir for example but it requires using the tracing infrastructure, not part of the log system and it’s part of the beam internals and doesn’t always correspond to elixir code due to its code generation.

I very much prefer OCaml straight over ReasonML. ReasonML just transpiles straight to OCaml anyway (and it can convert OCaml to ReasonML, it’s a lossless conversion, other than formatting just going bonkers, lol). But the OCaml syntax is so excessively more pleasant for me than ReasonML (which was designed to be a javascript’y syntax for OCaml, so it’s a lot more noisy).

2 Likes

I am back in this thread with a small review.

I have mentioned in the past that I will only skip the chapter involved with Web Frameworks in the book because neither of the frameworks (Amber and Kemal) really clicked, not to say they are bad frameworks, quite the opposite (I actually motivated a friend of mine to use Amber in his start-up for a small service and he loved it)- it’s just that I feel like it wouldn’t give me anything new. Unlike a programming language, investing in a specialized library or framework is a more time consuming one as it involves you to think up a non-trivial end product and go after it. Kemal is just Sinatra (or any of it’s brethren i.e. Express or Flask) crystallized.

But what I missed mentioning about is are the appendices. These are often not reviewed or talked about but in some cases, could give you a boost to get on with the rest of the book, In this case, it’s the latter.

There are three appendices here- 1. Setting up the environment, 2. Ruby to Crystal conversion and 3. Answers to the exercises. So the third one is your typical appendice that you only use as needed and may never care beyond that. But the setting up the environment one was pretty good. Except for the one where they claim about “nice IDE experience” in relation to VS Code. I don’t think that’s anywhere near nice. I can’t speak for other editors. But, I had forgotten about “Sublime Editor” when talking about Onivim to a former colleague of mine yesterday, I kept refering to as “… that fast editor that kept asking for money which I never used and promised not to ever use…”, she happened to forget the name too. So this appendix at least gave me that aha moment.

The next appendix, porting Ruby to Crystal, is just a table with syntaxes of the languages side by side. I am not a Ruby programmer but I can feel the convenience of having it. If one is a Ruby developer, I’d suggest skimming through that little table before any else. It’s weird, Java and Clojure belong to the same VM, but a table converting one syntax unit to other in entirety would not be useful at all (I am talking as a whole, not just the interoperability part, that’s useful). Same goes for Scala and Clojure. But Ruby and Crystal makes sense, they’re both the same paradigm-wise and philosophy-wise, has an overlap in the community and libraries with similar pattern. This makes total sense. Probably, Erlang and Elixir would be in this group too, but I think Ruby knowledge gets you close to Crystal knowledge faster than Erlang would to to Elixir, initially (eventually the role is reversed, knowing Erlang well helps with in your Elixir journey better as you tackle advanced things, Ruby/Crystal, may not be as much).

So, this is my penultimate thought regarding this book. Should have been the last one but I kept the advanced chapter, which I would tomorrow. After this, I will just note down any Crystal things I do.

One nice side-effect of this book though, I feel like I know more Ruby now! :smiley:

3 Likes

If you want to learn an interesting web framework that is ‘different’ I’d recommend Rocket in Rust, it’s method of handling ‘how’ a route is acquired and the variety of ways it can be skipped and so forth is fascinating!

Something more Phoenix-like in Rust in Warp, it’s concept of filters is essentially identical to Plugs in Elixir. ^.^

(Honestly Rocket’s style is like plugs/filters but baked in to the very types that the route function accepts, which makes it amazingly succinct and clear compared to the filter style!)

2 Likes

I do want to learn a web framework that is different. Only problem for me with Rocket is, I have 0 Rust knowledge. I do have it in my to learn list.

2 Likes

After OCaml, I’ll start a thread on Rust.

2 Likes

Chapter 8 - Advanced Features

Finally, my final chapter! This is an interesting one, I learned quite a bit from here, though I think each of the major features deserved its own chapter instead of a section.

So, advanced crystal here is comprised of-

  1. Macros
  2. Concurrency
  3. C-binding and
  4. Database Access

First, let’s check out Marco. I remember teaching Macro to a Django Developer colleague through Django templating language. It was very effectively communicated I believe. I was happy to see Crystal being much closed to the Django Template syntax than Clojure (my only macro example back then). It has {{}} and {% for <loop> %}...{% end %}. I think the chapter does great in explaning macros both in terms of what they are and how they are implemented in Crystal. method_missing, inherited, extended and included are hook-ish Macro-s that you can define to metaprogram on specific events (i.e. what happens when a method is missing? A subclass is defined? etc). I only tried out method_missing on playground, rest will follow. But it does seem straight forward.

Next comes C binding. This too looks quite simple in Crystal (compared to any other language I used). I got introduced to “annotations”, “lib” and “fun” syntaxes! I don’t recall having seen them described earlier. Anyways, upon visual inspection- lib is grouping of C libraries and fun inside a lib is a signature by signature mapping of same named C functions (More new syntaxes: * at the end for pointers that were introduced in this chapter). Annotations would map the C library with the following lib block. After this setup is made, we’re pretty much back to Crystal-land calling the FUNctions.

However, upon inspecting the Crystal Docs, there seems to be a lot more in binding Crystal with C than it was mentioned in the book (though it is suggested to reach out to that link to know more). Examples include, unsafe, enums, threadlocals, callbacks and many more. I think C <> Crystal is a big selling point for Crystal and from whatever I have skimmed through (have not executed anything) I do seem to be impressed at the simplicity of it. I would have been a lot happier if there were an example that does more than just a C void greet(const* char) function being called from Crystal, but something a little more. Perhaps the temperature converter mentioned in the first chapter? Or the Mineral system in the subsequent ones converted into struct?

One other thing, this chapter mentions once- “C is a strongly typed language” where it should have been C is a statically typed language. “Strong” and “Weak” typing is rather relative in my opinion and also in my opinion, “Strongly Typed” is not really a strong suit of C-s, it’s rather on the “weaker” end when it comes to “strength” of typing. Again, very nit. Also, I got to learn of system in Crystal which lets you execute an OS command (as does backticks, though not mentioned in the book).

Anyways, this book is not a reference and it DID do a great job of pointing me to the right direction after motivating me enough. Also, this chapter, particularly this section, had inspired me to continue playing with Crystal, so that too is a good thing.

After C-binding came concurrency. Crystal concurrency is like Go concurrency where go is spawn. You have channels, channels can be buffered, selected, yielded etc. The unit of concurrency is called Fiber. I think anyone understanding the conveyor belt metaphor and Go’s way of concurrency will find it easier to understand Crystal’s point of view. And in my opinion, Crystal does it with a much more beautiful syntax:

def generator(n : T) forall T
  chan = Channel(T).new
  spawn do
    loop do
      sleep n
      chan.send n
    end
	end	
  chan
end

ch1 = generator(1)
ch2 = generator(1.5)
ch3 = generator(5)

loop do
  select
  when n1 = ch1.receive
    puts "Int: #{n1}"
  when f1 = ch2.receive
    puts "Float: #{f1}"
  when ch3.receive
    break
  end
end

^ Another example from the book.

Final section for this chapter was DB integration. The pattern is simple:

DB.open do |db|
  db.query sql do |r|
    <do your thing with `r`>
  end
end

And that db also has exec, query_one, query_all etc. It only briefly mentioned Transactions at the end but looking at the design pattern, it’s simple to guess: db.transaction do |tx| ... end, I verified my guessing from Crystal docs.

So this was the final chapter highlights from my side. I left one out (the one with web frameworks) but I will revisit it from a “meta” viewpoint if I look into a Crystal framework, but that will be my highlights on the framework, not the chapter, and it may happen much later. As far as chapter-by-chapter exploration is concerned, I am finished here :smiley:

I could go on and on about how this book club journey has been for me (It was obviously good, I learned a language in ~40 posts!), but I will keep that for my upcoming post where I will summarize my experience, as for conclusion of this chapter/post, I will summarize my overall feelings of this chapter.

It was a “heavy” chapter, a lot of concepts to swallow in one unit. I wish this chapter was a PART with at least three chapters- Advanced Syntax (Macro + Generics maybe?), C-Binding, and Concurrency. The chapter on Database could’ve been merged with the Web Frameworks chapters. However, it is my opinion based on my worldview of things and this really is not a bad thing of this book. This chapter did a great job by having me see all these things and occasionally try them out in one weekend evening. I understand those things are out there in the docs, but the book prepared and outlined all the things and placed it in the right sequence of the ToC and got me there, if I am ever to deal with a problem in Crystal that does any of these, I am prepared, the remainder of the execution is the reference docs and my effort’s job. Despite my nitpicks and complaints, I will give it 4/5, based on the benefits I received from reading it!

Yes, I will continue with Crystal, and possible this year’s Advent of Code will be divided between Crystal and OCaml for me :smiley:

2 Likes

One pain point of my using Crystal! The crystal play borne playground is painful! When I copy the code from the book and paste it there, clicking on Run Formatter does nothing. The error labels often do not go away, and it crashed on my multiple times. Not sure it should be supplied with a Version 1.0 system.

Maybe Elixir spoiled me, but having a good interactive system (along with good IDE integration) receive strong points from me and Crystal receives low points in them both.

2 Likes

Entirely correct. C is a statically weakly typed language. OCaml or Rust would be statically strongly typed languages. Python would be a dynamically strongly typed language. Javascript would be dynamically weakly typed. ^.^

I have a blog about these definitions somewhere… >.>

How very windows of that term. Generally greenthread or microthread is the term, but windows had an API for stackframe swapping that people (poorly) implemented greenthreads/microthreads on called the Fiber API. ^.^;

Oooo that gives me an idea for a rust async description…

OT but there are a couple libraries for C called libdill/libmill that add similar concurrency, one of them is a go-style system and the other is more traditionally C style, but same backend for both. ^.^

I’m curious about hearing of your comparisons. OCaml I really love as a language, though you can definitely feel a lot of the cruft in its age, it still ranks as one of my favs. I still say look at Rust, Rust was originally built on OCaml after all. :wink:

1 Like

You know what, I think I really should. I never fought back with the compiler so my Rust progress never happened beyond a day or an hour. I should leverage this social learning spree of mine and see if I can get any Rust.

Do you suggest any learning resources? Any books? Working by doing didn’t seem to help much with it.

3 Likes

The official “Rust Book” on the main website is fantastic learning material, but I’m of the opinion that 1-on-1 help is often the easiest and best way to learn (I’m a fan of socratic style teaching). I have some time at work today (yay Fridays) that if you want to then we can. I’m on IRC and Discord if you have a preference. I mainly use Clion and it has awesome pair coding functionality (though sadly I can’t use the mic/audio while at work) though I think vscode has similar features as well, I can use either if you want pair coding. :slight_smile:

2 Likes

Thank you very much! I will start Rust from tomorrow, opening a section on it like this one to ask questions. It would be super good if you’d help me out. And judging from your responses in this thread, I am confident those would be more helpful than the books :slight_smile:

I think to start with, I will mostly initially have asynchronously reviewable questions and Github PR-s… I already have a few projects in mind. To be able to be pair programming, I’d need some familiarity with Rust first (I am at Hello World level right now), and it would be great if you’re up for it at that time

I do have Clion. Is the IDE experience of Rust any good? I also checked my Manning and PragProg accounts, looks like I have all Manning Rust books/videos bought (Not sure why and how I did that), none of PragProg’s (Not sure why and how I didn’t do that). But I think you’re right, the official “Rust Book” might be enough, it’s written keeping “everyone” in mind, I felt like.

I can’t thank you and @AstonJ enough for motivating me through the journals. I have learned more Crystal and OCaml than I would have if done solo. I am hoping the have better experience with Rust since I have more than just “Advent of Code” and Syntax-level interest in this one :slight_smile:

2 Likes

I wish I was as fast a reader as you Mafinar! We definitely have to do some Rust book clubs (I already bought #book-hands-on-rust) but just gotta finish Programming Erlang Book Club first. I hope to get back into it all soon tho - I’ve nearly finished porting our portal system over to one site, then it’s just one more after that and I’ll have more time for books :smiley:

You’re welcome and thank YOU for doing them! I’ve enjoyed following all of yours (and everyone else’s) journals and book clubs :blush:

1 Like

My need for sleep is 3/4 hours a day (any more than that on a non-sick day and I get migraine). So time is on my side; the true enemy is procrastination. Which is why I found this forum to be so useful, I can just jump right in and people join, help and motivate.

2 Likes

On weekends I’m mostly watching a baby so I won’t have any real computer time, but feel free to ask me questions on Discord or so and I can answer in mostly real time. :slight_smile:

Clion and RustAnalyzer (an LSP server, mostly designed to work with VSCode) are the big Rust IDE’s out, they are pretty much on par overall but I still like Clion better as it’s an actual IDE with other useful IDE features, both are very good though. :slight_smile:

I can also help with OCaml questions, feel free to ask. ^.^

3 Likes

Yes, spent decent amount of time reading the Rust book and coding some Advent of Code. Feels like this time I won’t give up.

I am starting a thread on it soon. The amount of lessons I learned from just doing 2 day 1 level Advent of Code in Rust is crazy!

My apologies in advance to @OvermindDL1 for all the silly questions I’ll be asking.

2 Likes

Lol! Remember, if you have a question then other people do too, so it’s good to publicly document it! ^.^

1 Like

Hi folks !

Sorry for the radio silence but I was quit busy later. I’ve get another job and thus, I documented all the stuff etc, it took me a lot of time and energy.

I can start reading and giving you my feedback on the chapters in a couple of weeks.
But unfortunately I would not be able to compare Go and Crystal since I’ll not work with Go.

Hope you’re all well !

3 Likes