Skip to content

Instantly share code, notes, and snippets.

condition = false
puts "hello" if condition
#=> nil
# note there is no printing of `hello`, this means `conditions` was evaluated first before performing the preceding code
# this is expected and expanding the preceding code into `begin...end` yields you the same result
condition = false
begin
puts "hello"
end if condition
@choonkeat
choonkeat / CmdWorkerPool.elm
Last active May 31, 2020 14:11
Module that allows Elm app to execute N `Cmd` in parallel (queue the remaining `Cmd`), when one is done execute the next Cmd in queue
module CmdWorkerPool exposing (Request, State, init, request, update)
import Task exposing (Task)
{-| State
- workersLimit limits the maximum number of concurrent Cmd
- workersCount tracks the current number of Cmd in progress
- backlog stores a List of Cmd that are waiting to be dispatched

A very common thing that tripped up my colleague: she had a User type alias record,

type alias User = { name : String, age : Int }

This means if you have a x value of User type, you can x.name or x.age as expected. So far so good.

In her function, it was passed in as argument but as a Maybe User

npm init --yes
npm install --save elm elm-live
elm init
@choonkeat
choonkeat / explicit-better-than-implicit.md
Last active March 6, 2020 16:50
"Explicit is better than implicit." Python said it first, but Python didn't say much

the init function in Go

If you're unfamiliar with it, here's a short paragraph

package mylib

func init() {
    defaultClient = new(42)
}

TLDR: you have to find the underlying context of the advice; when is it good for what. when you have your own reasons to adopt, then you'll also know when to let go (not wait for someone else to disband the party)

Don't just blindly follow the advice of "experts", take it with a grain of salt.

is prudent advice regarding following advice... but not enough; it's just varying the level of trust. Instead of only adjusting trust % level on what people tell you, try it out. for real or thought experiment on your past projects.

e.g. coming from years of writing Ruby to writing Go, i was accustomed to plucking the values out from os.Getenv wherever I needed it; there's a certain "plug and play" to doing things this way. chuyeow's PR reviews kept pointing out that cli flags are preferred and that it's ok to pass them in through function arguments to where I needed to use them. Though I didn't agree with the practice, nor could I see why it would be good in Go context, I went with it to see how things will pan

type fataler interface {
Fatal(...interface{})
}
func logJSON(t fataler, w io.Writer, label string, callback func() (interface{}, error)) {
data, err := callback()
if err != nil {
t.Fatal(err, label)
}
# Put your entry point make targets above this line
# Put build targets that are NOT meant to be entry points
# inside a different file. This way, when invoking shell
# autocomplete with `make <tab>`, only the targets in the
# main `Makefile` will be listed as options
include Makefile.libs
# make target for files are usually intentional

After getting over the initial language syntax hump, I found that what I needed isn't more "how to do this feature" kind of content.

I felt getting familiar with the language's core libraries was more useful; knowing what are the things I could do with the values I have on hand, I could come up with my own solutions.

TIP: The trick is to have this simple mindset: if you have a List of something, look at the List documentation, if you have a Maybe, look at the Maybe documentation, etc etc...

Also, Task and Result seem intertwined but I can't tell when/how to employ them.

TIP:

  • Result is usually a return value representing something that could be error. (Some languages choose to either return the successful value or throw an exception, so

A note about "type signature" and "type variables"

convert : Exchange from to -> Currency from -> Currency to

from and to are type variables to ensure things line up.

They are not variables in the regular sense: we cannot use from or to in our function body to + or do anything with. Actually, in our function body, there is no variable from or to