These are chat archives for dry-rb/chat

27th
Apr 2016
Tim Riley
@timriley
Apr 27 2016 06:28
Realising that Dry::Types::Structs with maybe values makes things difficult when trying to get a hash structure that can convert to JSON nicely
I’ve made a function that deep unwraps Maybe values
but I’ve just realised that Struct#to_hash in the first place doesn’t run to_hash across the values of arrays.
I thought: "this is probably a bug, so I’ll look into fixing it."
Then I realised, what if it’s a Types::Maybe::Strict::Array?
Then it’d be a Some([“the”, “array”])
And Kleisli::Maybe certainly doesn’t respond to #to_hash
This makes me think that Struct#to_hash probably isn’t what I want at all in order to prepare data to go to JSON
I think I might have to write that as a standalone transformation function that does a lot more unwrapping
Piotr Solnica
@solnic
Apr 27 2016 07:52
@timriley Use a dedicated tool for building json docs like roar or yaks
to_* methods are not sth you can depend on in the long term anyway
Tim Riley
@timriley
Apr 27 2016 08:23
@solnic thanks for the tip (and the intervention before I got too far with this!) - it makes a lot of sense.
Piotr Solnica
@solnic
Apr 27 2016 08:31
@joevandyk this is a decorator, you should instantiate it with sku injected into constructor
setting ivar in call looks rather odd
besides, it’s a predicate, so maybe having an object with a bunch of predicate methods would be better?
Andy Holland
@AMHOL
Apr 27 2016 11:29
FWIW the whole monads by default in dry-types seems too opinionated to me
Tim Riley
@timriley
Apr 27 2016 11:30
You only get them with “Maybe” types, though, @AMHOL? You could just not use them?
Andy Holland
@AMHOL
Apr 27 2016 11:31
Yeah, it's just not 100% clear whether .maybe is synonymous to .optional with the result wrapped
timriley @timriley wonders how much we care about jruby-head in travis
Andy Holland
@AMHOL
Apr 27 2016 11:37
We don't, it's an allowed failure across the board AFAIK
Tim Riley
@timriley
Apr 27 2016 11:38
Yeah. Travis won’t give the :ok_hand: to us until it’s completed even the allowed failures. And jruby is slow :)
Andy Holland
@AMHOL
Apr 27 2016 11:38
Yeah, that is kind of annoying
Tim Riley
@timriley
Apr 27 2016 11:55
Looks like we can make auto_inject work better with inheritance. It’ll require Ruby 2.2’s super_method:
    def define_constructor_with_args
      instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def initialize(*args)
          super_arity = method(__method__).super_method.arity
          super(*args[0..super_arity-1])
Andy Holland
@AMHOL
Apr 27 2016 12:04
What about splat arguments?
Tim Riley
@timriley
Apr 27 2016 12:05
yeah, working through all the cases now
Andy Holland
@AMHOL
Apr 27 2016 12:06
Cool
Tim Riley
@timriley
Apr 27 2016 12:06
#arity is not a bastion of straightforwardness :grimacing:
Andy Holland
@AMHOL
Apr 27 2016 12:06
I think we should support 2.0+ BTW
Indeed it is not
Tim Riley
@timriley
Apr 27 2016 12:07
I suppose we could check for whether respond_to? :super_method in order to keep 2.0 support
it’d just be broken though
Benjamin Klotz
@tak1n
Apr 27 2016 12:07
good old #arity :D
I remember trying to fix a bug in rbx about proc arity :D
Tim Riley
@timriley
Apr 27 2016 12:07
(in certain cases)
Benjamin Klotz
@tak1n
Apr 27 2016 12:08
so if you hit any bugs with some weird ruby magic on rbx just ping me maybe I can help (:
Tim Riley
@timriley
Apr 27 2016 12:08
Thanks!
          super_args = if super_arity == 0
            []
          elsif super_arity < 0
            args
          else
            args[0..super_arity-1]
          end
Pretty sure that covers it...
(famous last words)
Andy Holland
@AMHOL
Apr 27 2016 12:36
module Mixin; def initialize(test); end; end

class Parent; end
class Child < Parent; end
class ChildWithMixin < Child; include Mixin; end
class GrandChild < ChildWithMixin; end

def super_arity(klass, method)
  ancestors = klass.ancestors - [klass]
  container = ancestors.find { |k| k.method_defined?(method) } || klass
  container.instance_method(method).arity
end

super_arity(Parent, :initialize)
# => 0
super_arity(Child, :initialize)
# => 0
super_arity(ChildWithMixin, :initialize)
# => 1
super_arity(GrandChild, :initialize)
# => 1
Seems to work
Tim Riley
@timriley
Apr 27 2016 12:37
That’s clever!
Andy Holland
@AMHOL
Apr 27 2016 12:38
(famous last words) :laughing:
It's also incorrect :p
Tim Riley
@timriley
Apr 27 2016 12:40
oh?
Andy Holland
@AMHOL
Apr 27 2016 12:41
It will return the arity for the current method if it can't find a method in ancestors
Tim Riley
@timriley
Apr 27 2016 12:41
ah
Andy Holland
@AMHOL
Apr 27 2016 12:55
Weird, looks like method_defined? always returns false for :initialize
Luca Guidi
@jodosha
Apr 27 2016 12:56
Hi all. I'm trying to integrate again dry-v as backend for hanami-validations. To do so, I'm writing a lot of tests and there are unexpected failures. They looks like dry-v issues. Is it fine with you if I open GH issues for them? I'm asking here before to proceed. Thanks.
Andy Holland
@AMHOL
Apr 27 2016 12:57
Hi @jodosha, glad you decided to go with dry-v, please open away :)
Luca Guidi
@jodosha
Apr 27 2016 12:58
@AMHOL Thanks!
Piotr Solnica
@solnic
Apr 27 2016 13:19
@jodosha thanks, what about that idea to simply expose a proc for handling validations and just plug dry-v in w/o “hiding” its API? using it as a backend and hiding behind your own DSL will be quite some work eventually
Luca Guidi
@jodosha
Apr 27 2016 13:19
@solnic here it is:
      def validations(&blk)
        self.schema = Dry::Validation.__send__(_schema_type, &blk)
      end
That means:
validator = Class.new do
  include Hanami::Validations

  validations do
     # block to forward **as it is** to dry-v
  end
end
@solnic no special tricks that got me stuck in the past. That block is passed as it is to dry-v
Piotr Solnica
@solnic
Apr 27 2016 13:21
ah right, so you want the hanami-v extension
Luca Guidi
@jodosha
Apr 27 2016 13:21
That is useful for semver, extra builtin predicates, I18n paths..
Piotr Solnica
@solnic
Apr 27 2016 13:21
sure thing
@jodosha I’m working now so if you have any questions/need help just post it here and I’ll take a look in the evening
working as in mojotech’ing ;)
Luca Guidi
@jodosha
Apr 27 2016 13:24
@solnic Thanks. Have fun!
Piotr Solnica
@solnic
Apr 27 2016 13:24
(i-am (having (fun)))
Luca Guidi
@jodosha
Apr 27 2016 13:26
:D
Andy Holland
@AMHOL
Apr 27 2016 13:26
@timriley think I've found a solution:
module TestMixin; def initialize(test); end; end

class Parent; end
class Child < Parent; end
class ChildWithMixin < Child; include TestMixin; end
class GrandChild < ChildWithMixin; end

def super_arity(klass, method)
  method = klass.instance_method(method)
  owner = method.owner
  owner.equal?(klass) ? 0 : method.arity
end

super_arity(Parent, :initialize)
# => 0
super_arity(Child, :initialize)
# => 0
super_arity(ChildWithMixin, :initialize)
# => 1
super_arity(GrandChild, :initialize)
# => 1
lol @solnic
Tim Riley
@timriley
Apr 27 2016 13:28
Thanks @AMHOL, will try that once I’ve sorted out my current predicament
in which method(__method__).super_method inside auto_inject’s dynamically-generated #initialize is actually referring to itself when called via super in a class’ own normal #initialize :weary:
It’s like it’s being run inside the context of the normal #initialize
I basically just want to skip it in arity checks.
I think I might need to assign the anonymous module to a normal name via const_set so I can check it.
Andy Holland
@AMHOL
Apr 27 2016 13:36
@timriley as in the Dry::Injection module?
Tim Riley
@timriley
Apr 27 2016 13:36
nah, instance_mod
Piotr Solnica
@solnic
Apr 27 2016 13:37
@jodosha btw please use dry-v and dry-logic from master if it’s not a problem, additional testing will be helpful. we refined the DSL a bit so key(:foo).required became required(:foo).filled and added support for required(:something).value(:some?, :checks?, :go?, :here?). We had long discussions and concluded this will be nicer and with value API we can improve support for validating arrays and remove some ambiguity wrt “empty” vs “filled” values when dealing with different types. I can actually release dry-v 0.8 later this week
Tim Riley
@timriley
Apr 27 2016 13:38
@AMHOL
require "bundler/setup"
require "dry-auto_inject"

module Test
  AutoInject = Dry::AutoInject({ one: 1, two: 2, 'namespace.three' => 3 })
end

class Parent
  include Test::AutoInject[:one, :two, 'namespace.three']
end

class Child < Parent
  attr_reader :foo

  def initialize(*args)
    @foo = 'bar'
    puts "child initialize... done"

    # this will call the auto_inject-generated `#initialize` in an dry-
    # auto_inject-created anonymous instance module ancestor to `Parent`, but
    # inside that `#initialize`, if we run `method(__method__).owner`, it's
    # still `Child`, so when we use `super_method`, it's referring to our own
    # dynamically-generated `#initialize` method, from _inside that very same
    # method!_
    super

  end
end

Child.new
Piotr Solnica
@solnic
Apr 27 2016 13:38
there’s one more great benefit too, optional and required have the same num of chars so things align better :laughing:
Luca Guidi
@jodosha
Apr 27 2016 13:38
@solnic Awesome! That what's puzzling for me: optional(:foo).required(...)
Piotr Solnica
@solnic
Apr 27 2016 13:38
yeah exactly!
this was one of the reasons behind the renaming, prev key will continue to work and give deprecation warning
and prev required will give a deprec warning as well
Tim Riley
@timriley
Apr 27 2016 13:39
@AMHOL that kind of explains it in the comments, but I would guess it’s a tad vague without the code I’ve put inside the dynamically-generated #initialize
Piotr Solnica
@solnic
Apr 27 2016 13:39
@timriley really happy to see you working on auto-inject improvements, it’s been on my list for so long…<3
Tim Riley
@timriley
Apr 27 2016 13:40
@solnic glad to help! Having one of those metapgrogramming “fun” moments right now – probably means I should :zzz: on it, :satisfied:
Artem Pyankov
@iBublik
Apr 27 2016 13:49
@solnic in dry-v can I have custom messages for specific attributes? Something like this:
Cart = Dry::Validation.Form do
  configure do
    config.namespace = :cart
  end

  key(:foo).required
  key(:bar).required
end

Cart.call({}).messages # => { foo: 'is missing', bar: 'really need this!' }
Artem Pyankov
@iBublik
Apr 27 2016 13:53
Yeah, I've seen this. But there's no info about messages for specific attributes, only namespaces... Maybe I missed something...
Tim Riley
@timriley
Apr 27 2016 13:54
@AMHOL GOT IT
First, InstanceMethods = Class.new(Module)
And @instance_mod = InstanceMethods.new instead of Module.new
Then inside the dynamically-generated #initialize:
super_args = if super_init.owner.is_a?(Dry::AutoInject::InstanceMethods)
  []

# …
So now it won’t try and send the args to itself.
And all the tests are green!
Andy Holland
@AMHOL
Apr 27 2016 13:55
:D nice one
Tim Riley
@timriley
Apr 27 2016 13:55
And I am not a pumpkin!
Andy Holland
@AMHOL
Apr 27 2016 13:55
haha
Never doubted you for a second ;)
Tim Riley
@timriley
Apr 27 2016 13:56
I’ll try your 2.0 and 2.1 compatibility code later on, thanks for working that out!
Andy Holland
@AMHOL
Apr 27 2016 13:56
Cool, no worries
Tim Riley
@timriley
Apr 27 2016 13:56
:zzz:
Andy Holland
@AMHOL
Apr 27 2016 13:56
Night :moon:
Piotr Solnica
@solnic
Apr 27 2016 14:38
  rules:
      email:
        filled?: "the email is missing"
@iBublik ^^
it's all there, but I can see how this could be explained nicer
Artem Pyankov
@iBublik
Apr 27 2016 15:23
hmm, doesn't seem to work for me...
Piotr Solnica
@solnic
Apr 27 2016 15:24
@iBublik do you use it with a namespace?
in your example you have a namespace set, if that's what you want then nest the messages under that namespace in config
Artem Pyankov
@iBublik
Apr 27 2016 15:55
I've tried this config:
en:
  errors:
    rules:
      cart:
        foo:
          key?: no_foo
        rules:
         foo:
           key?: no_foo
with no success :disappointed:
@solnic ^^
Piotr Solnica
@solnic
Apr 27 2016 15:58
@iBublik and w/o a namespace?
Artem Pyankov
@iBublik
Apr 27 2016 15:59
I've tried to remove namespace, same result
following config returns no_key message, but this isn't what I want - I want specific message for specific key. I'll continue to investigate
en:
  errors:
    rules:
      cart:
        key?: no_key
Piotr Solnica
@solnic
Apr 27 2016 17:11
@iBublik seems like a bug. please report an issue
dan-klasson
@dan-klasson
Apr 27 2016 17:42
@solnic you've mention a few times that you fear the demise of the ruby language. i'm curious what your thoughts are about the crystal language, if static ruby could be the future and how the dry/data-mapper/rom would fit in in such a transition
Piotr Solnica
@solnic
Apr 27 2016 17:43
@dan-klasson crystal is really nice, I'm watching its evolution. personally I'm more interested in FP langs and that's my direction in the longer term
dry/rom relies on various meta-programming features of Ruby so I'm not sure if we'll be able to make them work
ie rom relation methods can be auto-curried, which uses method decoration trick. or dry-auto_inject uses module subclassing
re my fear, it's mostly related to rails obsession, the lang and its ecosystem could've been much better if people were not so focused on this one framework
Jeff Dickey
@jdickey
Apr 27 2016 17:49
true. the best thing that ever happened to Ruby as far as wide usage goes, was Rails. The worst thing that could possibly have happened to Ruby, in terms of the language and ecosystem, was Rails. It defies comprehensibility, and has worked hard to "earn" that
jdickey @jdickey crawls back under a rock; done venting after having a very long fortnight today battling the magalith
Jeff Dickey
@jdickey
Apr 27 2016 17:50
sorry
dan-klasson
@dan-klasson
Apr 27 2016 17:56
@solnic that's interesting. what kind of functional programming languages do you like and do you think they could gain more traction than other languages such as crystal and go?
Tanner Donovan
@ttdonovan
Apr 27 2016 17:56
@jdickey I would agree with that statement. Once developers have become more experienced or applications have outgrown Rails - it's important that their are other communities or ideas of better practices - thankful there is the dry-rb ecosystem, frameworks like Hanami and Rails opinionated extensions like Trailblazer.
Piotr Solnica
@solnic
Apr 27 2016 17:57
for me fundaments of a lang ecosystem should consist of low-level robust composable libs, not frameworks, frameworks are "just" a convenience
frameworks play major role, sure, but if this role is 10 x bigger than libs then we have a problem
this is what's been happening in ruby
Jeff Dickey
@jdickey
Apr 27 2016 17:58
Rails is amazing for getting tiny CRUD demos up and working. But that's not sufficient for even an MVP anymore, and _growing a Rails app is _hard; IMO they've been going in very wrong directions post-Rails 3.2 or possibly even 2.3.
Artem Pyankov
@iBublik
Apr 27 2016 17:58
@solnic yep, it looks like there's a bug. I can't define custom message for key? predicate, bu I can do it for filled? :)
Piotr Solnica
@solnic
Apr 27 2016 17:58
@iBublik what a funny bug :) please report, I'll be wrapping up 0.8.0 later this week so I'll fix it for that release
dan-klasson
@dan-klasson
Apr 27 2016 17:59
well at least rails is not written in PHP ;)
Piotr Solnica
@solnic
Apr 27 2016 17:59
@dan-klasson I'm learning Clojure as we speak
@dan-klasson I'm also doing Elixir from time to time and eventually I want to learn Haskell
Jeff Dickey
@jdickey
Apr 27 2016 18:00
that's one of the problems, actually; too many of us came to Ruby from PHP and brought that bastardised thinking about object-orientation, particularly "no class is too large or too complex", with us
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:00
@solnic That reminded me of the javascript ecosystem. Lots of different libs with similar functionality. Maybe too many?
I mean node.js
Piotr Solnica
@solnic
Apr 27 2016 18:00
@ggayan well, they don't have a stdlib
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:00
hahah that's true
Jeff Dickey
@jdickey
Apr 27 2016 18:01
yeah; rotsa ruck to anyone who tries to define a "standard library" for JS; I think Node is as close as it's ever going to get, may $DEITY have mercy on all who go into that tar pit
Piotr Solnica
@solnic
Apr 27 2016 18:01
node is abomination anyway and it's JS
at least there's ClojureScript and Elm
Jeff Dickey
@jdickey
Apr 27 2016 18:02
true. But Zend was at least as bad for years and years and too many corps standardised on it to write their new corp codebase corpses
In the event that I actually get some free time this year, I intend to come up to speed on Elixir. Clojure…I ran away screaming from Lisp 20+ years ago and it's going to take a lot to get me to stick my toes in THERE again
dan-klasson
@dan-klasson
Apr 27 2016 18:04
rails might be a mess. but at least it's using a real language that doesn't suck as bad as PHP. because to this day, most web dev is done in that horrible language
Jeff Dickey
@jdickey
Apr 27 2016 18:04
Sure, and people shipped apps in RPG for a decade or two after that was seen to be an extremely efficient road to perdition — because people shipped apps
there will always be the Bastard Language Hell Threw Out; for the current generation, that honour belongs to PHP. 7 has some nice candy, but it hasn't leached out the strychnine permeating the accreted mass
dan-klasson
@dan-klasson
Apr 27 2016 18:06
and when i started doing programming, everyone were doing ASP. gradual improvements i guess
Jeff Dickey
@jdickey
Apr 27 2016 18:07
yeah, and ASP actually turned into a fairly decent language after how many years?!? But anybody who's sat around the php_core mailing list (or whatever they're calling it nowadays) knows that isn't going to happen; too many egos invested in the toxicity
Ruby has its faults, but it's amazing how many of them move around nwhen you switch interpreters
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:09
I've been thinking for some time about debloating some of our rails apps. I feel like dry-rb libs point to the right direction, but I also stumbled upon trailblazer. What are the thoughts of this community about it (trailblazer)? Is it worth it?
I noticed that trailblazer reform can use dry-validation as a backend
Was that a joint effort?
dan-klasson
@dan-klasson
Apr 27 2016 18:13
@ggayan the TRB community is pretty active. whether it and/or dry-rb will be the next big thing is anybody's guess.
Tanner Donovan
@ttdonovan
Apr 27 2016 18:13
I like some of the ideas but it might be to opinionated and still coupled to Rails - I think a better approach is creating your own Ruby gem of business domain entities and services and including it into a Rails application is an better approach (follow something like https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html) as far as frameworks I'm liking Hanami.
dan-klasson
@dan-klasson
Apr 27 2016 18:13
yes, it was a joint effort. mainly between Piotr and Nick I think
@solnic so how come you wanna learn static and dynamic functional programming languages that differs greatly from ruby? curiosity or because you believe it will have more traction in the future?
Jeff Dickey
@jdickey
Apr 27 2016 18:15
we've been developing on MRI, but I'd be surprised if we're still even developing against it by this time next year. @ggayan, IMO Trailblazer has a lot of good ideas, and some of the parts (Roar; Cells if it works for you) are great…but I think @ttdonovan is right; it's still too in love with Rails. We're not auite to the point where we declare ORMs to be the work of the devil, but at least a data-mapper approach lets you understand the moving parts
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:15
Thanks for the link @ttdonovan, I'll take a look at it. I didn't know about hanami. I really liked Lotus though.
Jeff Dickey
@jdickey
Apr 27 2016 18:15
@dan-klasson can't speak for @solnic but as someone who's been paid to code in over 40 languages thus far in my career, you can never have too many tools in your chest
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:16
It seems that lotus is hanami now from what I'm reading :P
Jeff Dickey
@jdickey
Apr 27 2016 18:16
yep; thank American trademark law for that
Tanner Donovan
@ttdonovan
Apr 27 2016 18:16
yes lotus was rebranded as hanami
dan-klasson
@dan-klasson
Apr 27 2016 18:18
I think the only reason that TRB is "in love" with Rails is because there are few alternatives out there. The whole point of TRB is to use a higher level architecture that can be applied in any framework. It's just natural that the creator of TRB would focus on Rails because that is what most people use. Also, the beauty of TRB is that you can gradually transition your code base to it. Then switch to Sequel, ROM, and even Hanami routes and controllers. I think what dry-rb and TRB have in common is that they are not trying to force a kitchen sink on you.
Yeah and I was thinking about that too. Surely Trailblazer (the car), is also trademarked. But maybe since it's not in the software dev business it doesn't apply as much,.
Jeff Dickey
@jdickey
Apr 27 2016 18:19
True, and kitchen sinks do hurt when they hit you and your stakeholders on the head
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:21
What I like about TRB is that is encouraging existing rails devs to start thinking in terms of smaller objects
Jeff Dickey
@jdickey
Apr 27 2016 18:21
who's going to confuse the Jeep with the framework? Only a legal team uncaring about taking their client's money to get laughed out of court. There's boatloads of precedent for that widely-differing usage of similar/identical trademarks
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:21
I really dislike rails fat-models philosophy
Jeff Dickey
@jdickey
Apr 27 2016 18:22
that's the big thing; models that have domain logic are the spawn of the devil, full stop. Worse are controllers; figuring out how to do those properly takes a lot of Rails devs a good year or more, or two-three failed projects
especially with Rails 5 landing on us imminently, where you're told "don't test controllers except as black boxes; pay no attention to the man behind the curtain, especially if he is you"
one can appreciate the sentiment while still being appalled at how easy it is to migrate domain logic into ApplicationController
Gabriel Gayan Fanta
@ggayan
Apr 27 2016 18:25

are you referring to rails/rails#18950 ?

edit: syntax

dan-klasson
@dan-klasson
Apr 27 2016 18:25
@jdickey It doesn't take that long. It just takes longer. And at the end of it you're left with this thought, there is bound to be a better way to do this. And there are lots of better ways, like using service and value objects. But I think the problem is that there is no uniform way, so everybody ends up implementing it differently. Most of which doing it the "Rails way", with fat models or the horrors of concerns and the likes
Jeff Dickey
@jdickey
Apr 27 2016 18:28
yep, that's the problem. everybody has to learn the same thing from first principles, or from looking at a dozen or so Gems that various folks have published saying "here's how we did it". We're on our sixth or eighth iteration of that, depending on how you count generational breaks, in the last four and a half years. That's flat-out not sustainable.
dan-klasson
@dan-klasson
Apr 27 2016 18:30
but then again, most devs work on small apps and will never come across this problem. but the people who do, end up in channels like this one
Jeff Dickey
@jdickey
Apr 27 2016 18:32
what grinds my_ gears into dust is how big and interconnected classes tend to get if you don't exercise _iron discipline. Without a proper framework, people get used to this superstition that creating lots of small classes or ensuring immutability are somehow "hard" or "expensive". My fave languages were Smalltalk and Eiffel, back in the day, and even for me, my first two years of throwing myself against Rails just twisted my object thinking
@dan-klasson That's certianly a huge part of it, and indicative of the mindset. Why were instance variables being tested anyway? Because there was no better, more reliable way to implement (or test) effects of a controller. Fix controllers, and people will stop doing Stupid Testing Tricks
Jeff Dickey
@jdickey
Apr 27 2016 18:42
and is anyone else having problems with the Gitter client (Web or app, either way) neglecting to leave italic/bold when you tell it to? I thought I was seeing things, or maybe a bug in the client, but it's not just the one client
Piotr Solnica
@solnic
Apr 27 2016 18:52
@dan-klasson I started writing ruby in functional style so...feels like a natural next step for me to switch to a functional language