Threads for dorianmariefr

    1. 4

      Company: thoughtbot

      Company site: https://thoughtbot.com

      Position(s): https://thoughtbot.com/jobs

      Americas

      Europe, Middle East, Africa

      Location: REMOTE

      Description:

      thoughtbot is your expert design and development partner. We bring digital products from validation to success and teach you how because we care. It’s time to move beyond simply building features and start designing the right product with the right strategy.

      Tech stack: Ruby, Rails, JavaScript, Stimulus, React, SQL, PostgreSQL, Heroku, AWS, Kubernetes (depends on the client)

      Compensation:

      For instance for “Ruby on Rails Developer” in Europe, Middle East, Africa it can vary between $57,000 and $125,000 USD depending on location and seniority.

      Equity would probably be for very senior roles

      All the benefits are on https://benefits.thoughtbot.com

      For instance for France, I have 25 days of vacation and 10 days of sick leave paid from the first day (not common in France).

      Contact: dorian@thoughtbot.com

      Hope it helps, it’s a pretty awesome company, you can read more about how we work https://thoughtbot.com/playbook and our values https://thoughtbot.com/purpose

      1. 4

        Thanks for posting salary ranges!

    2. 6

      Company: GitHub

      Company site: https://github.com

      Position(s): engineering, product, design, and many other roles (but selfishly I’m looking for platform product managers)

      Location: US, Canada, Europe - remote or on-site

      Description: GitHub is the largest code hosting and devops service in the world. We have dozens of roles open, but I’m looking for two platform product managers. One is for Data Storage – we build the SQL, NoSQL, blob storage, event queue, and job queue systems for the rest of the company. The other is for Git Systems – we build storage and access mechanisms for Git data, and we contribute much of what we build upstream so everyone can benefit from it. (Job posting hasn’t gone live yet, email me at my-lobsters-username@github.com if interested.)

      Tech stack: Ruby on Rails, Go, Rust, C#, Kubernetes, Typescript

      Compensation: competitive salary and stock grants, discretionary PTO (most people aim for 5-6 weeks), home office and communications stipends, remote-first culture

      Contact: https://boards.greenhouse.io/github/jobs/4020477 or my-lobsters-username@github.com for the PM roles; https://github.com/about/careers for other roles

      1. 3

        Looks like I can no longer edit my post. The Git Systems role has been posted.

      2. 2

        I’m always surprised that at its scale (and being Microsoft), GitHub is still not hiring in some countries (such as France).

        1. 4

          I agree, it sucks. We can’t even hire in all of Canada, only certain provinces. Because we’re independent of Microsoft, we can’t use all of their nexuses of business, employment tax setups, etc.

          1. 1

            We go through remote.com

            1. 3

              For those wondering, “We” in the above post means Thoughtbot.

        2. 1

          French labour laws and regulations are off putting for many companies. We should stop pretending that’s not the case.

          1. 1

            I wonder which specific thing is off putting?

      1. 3

        If it doesn’t exist…that’s the plan. Initial research here because I couldn’t find anything obvious myself.

    3. 2

      This is an announcement to a list of articles about ruby, currently one: https://timriley.info/writing/2022/03/24/let-the-shape-of-the-code-reflect-its-flow/

      I would rather do Message.new(message).tap(&:decode).process or decode in the initializer, not sure

      1. 2

        In Clojure, the thread-first macro would be used instead of a chain calls in a readable way.

        (-> message decode build-event process)
        

        I’m not familiar with Ruby, but I’m guessing the chain of then calls can’t be collapsed?

        message.then(decode).then(build_event).then(process)
        

        I understand the author’s concern that not naming the intermediate values can make understanding the intermediate types unclear, but I think not having the names increases readability. In most cases, the intermediate structures are defined by or near the function definitions that use them.

        1. 1

          Unfortunately, Ruby doesn’t have first class support for functions - decode would be interpreted the same as decode() and would throw an ArgumentError. You would have to do something like message.then(&method(:decode)).then(&method(:process)).

          1. 7

            I’ve seen people say this a lot, that Ruby doesn’t have first-class functions, but I think that is wrong. It’s just not syntactically as convenient as other languages, but you absolutely can pass methods around as objects.

            operation = method(:decode) >> method(:build_event) >> method(:process)
            operation.(message)
            

            Method objects and procs/lambdas are interchangeable here.

            1. 1

              Here’s my response to whether Ruby has first-class functions: https://briankung.dev/2022/03/27/ruby-has-economy-class-functions/

              1. 1

                I disagree with your argument because the entire Higher-Order Functions section confuses the difference between methods and functions. All of the problems you demonstrate come from that misunderstanding.

                Next, let’s try to return functions from functions in Ruby:

                def returns_function
                  def addition(a, b)
                    a + b
                  end
                end
                

                You are not instantiating a function here at all, you are metaprogramming the receiver of returns_function to add a new method. There are times where you’d actually want to do this, but they have nothing to do with higher-order functions.

                add = returns_function
                #=> :addition
                add(1,2)
                (irb):10:in `<main>': undefined method `add' for main:Object (NoMethodError)
                

                You can do this pretty handily in Javascript:

                let returnsFunction = function() {
                  return function(a,b) {return a + b };
                }
                let addition = returnsFunction();
                addition(1,2);
                // 3
                

                Yes, doing two entirely different things behaves differently! Allow me to flip this comparison on its head:

                dog = Object.new
                def dog.bark = "woof!"
                dog.bark # => "woof!"
                
                function addBark (obj) {
                  obj.bark = function() { return "woof!" }
                }
                
                let dog = {};
                let bark = addBark(dog);
                
                bark() // Uncaught TypeError: bark is not a function
                

                Huh, JavaScript sucks at methods doesn’t it? (No, this was intentionally wrong)

                An apples-to-apples comparison looks a lot closer:

                Currying in Ruby

                addition = ->(x, y) { x + y }
                add_two => addition.curry.(2)
                add_two.(4) # => 6
                

                Currying in JS

                let addition = (x, y) => x + y
                let addTwo = (y) => addition(2, y)
                addTwo(4) // 6
                

                Ruby makes different tradeoffs between methods and functions than JavaScript or other languages. JS is more comfortable for pure functions, but methods are janky. Ruby puts most of its ergonomic focus on methods, with implicit block arguments fullfilling the majority of first-class function use-cases, and native procs and lambdas filling in the blanks.

                This leads to more complexity in some cases, it’s true. But some of the interactions between them is much richer than JS APIs can provide. For instance:

                require 'markaby'
                
                mab = Markaby::Builder.new
                mab.html do
                  head { title "Boats.com" }
                  body do
                    h1 "Boats.com has great deals"
                    ul do
                      li "$49 for a canoe"
                      li "$39 for a raft"
                      li "$29 for a huge boot that floats and can fit 5 people"
                    end
                  end
                end
                
                1. 1

                  I think you’re 1) making a strawman argument, and 2) ignoring the ergonomics of what first-class functions means. The fact that you have to think about any of this at all in order to use Ruby’s “first class functions” means you can only say it has them with a lot of disclaimers. As I put it in the post, “economy-class.” Note that I don’t deny that it technically has them!

                  JS is more comfortable for pure functions, but methods are janky. Ruby puts most of its ergonomic focus on methods

                  To be equally pedantic, we weren’t talking about methods, were we? We’re talking about first-class functions. Not first-class methods. Yes, the syntax you call out defines a method on the caller, but do programmers used to first-class functions want to think about that? No, they do not. In fact, the fact that the def keyword defines methods and not functions makes it even more clear that Ruby does not treat functions as first-class.

                  Yes, you can curry in Ruby. But it’s an incredibly uncommon pattern. Why? Because Ruby doesn’t treat functions as truly first class. You can do it - that was the whole point of my post - but it’s awkward. Wikipedia labels Ruby’s first-class functions support with the equivalent of asterisks:

                  • The identifier of a regular “function” in Ruby (which is really a method) cannot be used as a value or passed. It must first be retrieved into a Method or Proc object to be used as first-class data. The syntax for calling such a function object differs from calling regular methods.
                  • Nested method definitions do not actually nest the scope.
                  • Explicit currying with Proc#curry.

                  Also yes, you can do cool stuff with instance_eval, but that’s not what we’re talking about. We’re talking about language-level support for first-class functions.

                  1. 0

                    I don’t understand how that could possibly be construed as a strawman, the entirety of my comments were responding to the substance of your blog post. Unless you are referring to the JS example, which I pointed out directly was intentionally wrong to make a point.

                    The fact that you have to think about any of this at all in order to use Ruby’s “first class functions” means you can only say it has them with a lot of disclaimers. As I put it in the post, “economy-class.” […] To be equally pedantic, we weren’t talking about methods, were we? We’re talking about first-class functions.

                    Ruby has first-class functions without any disclaimers. My critique of your argument is that you keep confusing method invocation for function execution and these are two entirely different language concepts.

                    To be explicitly clear: when I say Ruby has first-class functions, I am speaking of Procs and Lambdas. Those are functions. Methods are not. Two different things.

                    1. Assigning a function to a variable
                    greet = ->(name) { "Hello, #{name}!" }
                    greet.("John") # => "Hello, John!"
                    
                    1. Passing a function as an argument
                    transform = ->(str, fn) { fn.(str) }
                    transform.("foo", -> { _1.reverse }) # => "oof"
                    

                    It’s also worth mentioning that your example:

                    array.select {|number| number.even? }
                    

                    You are demonstrating this property, which can also be written as

                    evens = proc { |number| number.even? }
                    array.send :select, &evens
                    

                    Block arguments are Procs that are passed as arguments to methods. This is the most common way of using first-class functions in Ruby, and it’s one of the most unique language features.

                    1. Returned as a result of a function
                    curry = ->(fn, x) { ->(*args) { fn.(x, *args) } }
                    addition = ->(x, y) { x + y }
                    add_one = curry.(addition, 1)
                    add_one.(1) # => 2
                    
                    1. Including a function in any data structure
                    transforms = {
                      reverse: -> { _1.reverse },
                      upcase: -> { _1.upcase }
                    }
                    transforms[:reverse].("foo") # => "oof"
                    transforms[:upcase].("foo") # => "FOO"
                    
                    1. Composing multiple functions together
                    reverse = -> { _1.reverse }
                    upcase = -> { _1.upcase }
                    shout_in_reverse = reverse >> upcase
                    shout_in_reverse.("foo") # => "OOF"
                    
                    1. Functions are closures

                    This isn’t strictly necessary to qualify as first-class, but I think it is the most common way to do it.

                    count = 0
                    incr = -> { count += 1 }
                    incr.() # => 1
                    count # => 1
                    

                    Is that more clear? Functions in Ruby are invoked with call which has syntactic sugar .().

                    Second, methods are not functions.

                    1. Methods are not closures
                    count = 0
                    def incr = count += 1
                    incr() # NoMethodError: undefined method `+' for nil:NilClass
                    

                    This happened because the execution binding of a method is the receiver, not the lexical scope. This is important because calling a method is essentially just syntactic sugar for send

                    This can be confusing in a REPL specifically, because it’s not clear from the above what you are actually doing. In a Ruby REPL, main is an instance of Object, and calling def is actually defining a new method on the Object class.

                    1. Method invocation is just send
                    dog = Object.new
                    def dog.bark = "woof!"
                    dog.bark # => "woof!"
                    dog.send :bark # => "woof!"
                    

                    Method objects exist so that you can translate the method interface into a function interface, but you’re really just bundling up the receiver together with a message to send

                    bark = dog.method(:bark)
                    bark.() # => "woof!"
                    
                    1. Methods can’t be detached from their receiver

                    A method is a type of message that an object can respond to. You can’t separate them (well, you can but UnboundMethod is not executable until it is bound to something)

                    A Ruby method is an implementation of the OOP idea of data and behavior existing together in a single object.

                    All methods have an implicit block argument (a Proc), which is a first-class function. The syntax of Ruby allows you to seamlessly combine methods and functions into a single interface, but there is no requirement that you do so.

    4. 2

      I use my Yubikey with ykman, e.g.

      ykman oath accounts code -s bugs.ruby-lang.org
      
      1. 1

        With some basic dmenu wrapper it’s been a perfectly viable solution for me too:

        #!/usr/bin/env bash
        
        set -o errexit -o nounset -o pipefail
        
        SERVICE=$(ykman oath accounts list | dmenu -i -f -l 16)
        
        CODE=$(ykman oath accounts code --single "$SERVICE")
        notify-send Yubikey "$CODE"
        echo -n "$CODE" | xsel -i -b
        echo -n "$CODE" | xsel -i -p
        
        (
            sleep 30
            xsel -c -b
            xsel -c -p
        ) &
        
    5. 2

      I was never really happy with any templating language, none of them ever really fit and customization was never satisfactory. I started using sh as templating language (https://mkws.sh/pp.html) and never been happier. Makes sense, UNIX tools are great for processing plain text and also for displaying plain text in as human friendly way as possible. Just use standard UNIX tools for processing and outputting the text in any kind of file types.

      1. 2

        😬 One rough consensus about templating languages is that they shouldn’t be too capable*; you want your logic in the program, not the templates.

        In light of that, a template language that’s capable enough to, say, upload all your data to Elbonia and then wipe your disk sounds particularly dangerous to me. What’s the pp equivalent of Johnny Tables?

        Plus the fact that sh has IMHO the ugliest syntax for conditionals/loops outside of Brainf*ck…

        * (I was going to say “they shouldn’t be Turing-complete”, but I wouldn’t be surprised if someone has figured out how to implement Towers of Hanoi in Liquid…)

        1. 1

          It’s a matter of responsability, who’s responsible for the safety, the programmer or the language? You ilustrated that pretty good with the Johnny Tables example, who’s responsabile for that, SQL (or C# I believe?), or the programmer? Any programming language is “dangerous”, also, any programmer.

          It’s as safe as any shell script you write locally and run.

          Ugly is relative, I also found it ugly initally, now I find it elegant.

          Logic is where you decide to put it, you could write separate programs for the logic the UNIX way and only use pp for presenting the output.

          In the context of using it for generating static HTML files, I personally prefer to see it as progressive enhancement for the CLI. You’re already using the standard CLI tools to show data on your terminal, why not use the same CLI tools to show data on a web site, considering a web site is just a way to show off local data in a public way.

          1. 1

            It’s as safe as any shell script you write locally and run.

            If you use it only with local data, yes. But templates very often run on untrusted data from the network. If your templater doesn’t escape that properly, it’s open to injection attacks; and if the data that failed to be quoted is part of a shell command, you’ve got a full RCE.

            logic is where you decide to put it.

            Sure, but there’s a lot of evidence from experience that it’s better to separate logic from templates.

            1. 2

              If you use it only with local data, yes. But templates very often run on untrusted data from the network. If your templater doesn’t escape that properly, it’s open to injection attacks; and if the data that failed to be quoted is part of a shell command, you’ve got a full RCE.

              Agree, I’m only using locally for now. In case of untrusted data, just make sure you properly sanitize it, again matter of responsability.

              Sure, but there’s a lot of evidence from experience that it’s better to separate logic from templates.

              Agree again, it’s a good idea to develop separate programs for logic and only use pp for displaying the output.

        2. 1

          I was going to say “they shouldn’t be Turing-complete”, but I wouldn’t be surprised if someone has figured out how to implement Towers of Hanoi in Liquid

          Liquid is definitely turing complete. Being amazingly poorly designed and not fit for purpose doesn’t not prevent completeness ;)

    6. 2

      Nice post! I did a similar project last year cloning Jinja in Python but writing the parser by hand.

      1. 2

        Thanks, the idea is that I can run user-written templates, e.g. I define the context, the methods etc.

        Kinda like liquid but more powerful and without the default standard library

      2. 2

        That post is really really cool, I use PEG but would like to be able to create my own PEG one day (I tried different ones and previously used PEG.js which is quite powerful).

        I read https://craftinginterpreters.com/ but mostly followed the examples.

        1. 2

          Can’t you use PEG to write your own PEG implementation?

          1. 1

            Too true, don’t know what to answer to that

      1. 2

        The syntax can be a little weird

        Of course, using children for literals is overly-verbose. It’s only necessary when nesting arrays or objects into objects; for example, the JSON object {"foo": [1, 2, {"bar": 3}], "baz":4} can be written in JiK as:

        object {
        	(foo)array 1 2 {
        		object bar=3
        	}
        	(baz)- 4
        }
        
    7. 1

      Job interviews

      1. 1

        good luck!

    8. 1

      I use Google Domains, no need for an extra account and secured through my Google account

      I sometimes subscribe to Google Workspace and most of the times I change the nameservers to Cloudflare

    9. 1

      I’m gonna redo the email verification for my app, let users edit their email, improve image generation, fix the title on Google, etc.

      Also need to check out of my apartment

    10. 9

      Water plants.

      1. 2

        Plant.find_each(&:water), easy?

        1. 3

          Sure, but is it concurrent? :)

          1. 1

            Parallel.each(Plant.all, &:water), there you go, infinite minions watering your plants

            1. 2

              Much better!

    11. 1

      Very nice, exactly what I needed!

      I should look into doing that for SES too

    12. 1

      Need to organize my first speed dating event to make my app profitable

    13. 2

      Company: Doctolib

      Company site: https://doctolib.com

      Position(s): Programmers

      Location: REMOTE and/or ONSITE

      Description: Booking doctors online and providing an agenda for doctors (it’s much more than that ;) )

      Tech stack: Ruby/Rails/Javascript/React for the monolith, then TypeScript for the Desktop App (Electron), React Native with a webview for native apps, PostgreSQL, AWS, Kubernetes, etc.

      Contact: dorian.marie@doctolib.com, I will redirect you to the correct contact, I’m just a programmer there :)

    14. 1
      • fixed small bugs and little improvements on socializus app
      • iterate on concierge app
      • receive friends
      • go to family gathering
    15. 4

      I don’t think this is very on-topic. A blog post containing in-depth content on exactly what makes this change worthwhile would be much more appropriate for Lobsters.

      I’m pretty happy about this pull request I made on rails

      Erm, congrats?

      1. 1

        agreed, it’s going to be in “this week in rails”, that will be more appropriate to post

    16. 1

      setting up a basic idea of my concierge service idea

    17. 3

      I just want to say that I hate stale bots, I just want to contribute if I found a solution to the bug or see the solution others have found

    18. 1

      should be a single table expressions IMHO

      1. 1

        How do you mean?