Given
{ a: { b: { c: 4 } }, d: 2 }
return { 'a.b.c': 4, d: 2 }
My go to solution uses mutable state, self-recursion, and intermediate variables: function flatten(source) {
var result = {}
_flatten(source, null, result)
return result
}
where `_flatten(source, prefix, result)` is self-recursive (`prefix` accumulates the keys) and populates `result[prefix]=value` when value is a string. `result` is conceptually an IO monad that's passed along.I guess the general problem would be traverse a tree of arbitrary depth and accumulate structured data on the go. Prominent examples would be compilers.
Any hints on where to start?
These rules are constraints on how to create your code
and are only intended to be applied when doing katas or
exercises.
These rules are an exercise to kick you out of an OOP mindset, not best practices for writing real code.By that same token, I think it is a good rule when practicing OOP to not allow bare functions. It helps train yourself to think "Is there a logical class that this method belongs to?" In real code, of course, the answer is often "no". But when first learning OOP, it's good to teach yourself to ask that question in the first place.
Your code isn't a good example of "the OOP way", though. A fluent OOP solution would be:
s = x.sin()
Another good rule when practicing OOP would be "No classes without state." That helps you avoid the habit of writing pointless "namespace" classes like the "Math" class you define here. Of course, again, sometimes it is useful to wrap a bunch of related behavior in a stateless class, but that should be the exception, not the default.Also, to reverse that perspective, a "type" in Erlang/Elixir-lang is just any data formatted in a way that a given set of functions will work with it, rather than requiring an explicit tag. {1, 2} can be an instance of a type†, if you have a module Foo that spits that shape of data in response to Foo.new/0 and takes it for Foo.change/1.
† An example of such a type is Erlang's http://erlang.org/doc/man/queue.html . queue:new/0 just returns {[], []}.
I can not see how they could be used to help escape analysis more than that you have one less reference (this).
I wouldn't expect anyone to follow them religiously in production code.
I disagree. Switch statements are fine to react to incoming data, but terrible for everything else. If you add a value to an enum you have to change every place where the enum is used in a switch. And the code inside the switch is not reusable (Unless you make it a method, at which point you're close to the "OOP" way anyway). I agree that religiously avoiding switches lead to spaghetti code, but mindlessly using them does so too.
m = new Math() s = m.sin(x)
would be "the OOP way" instead of x.sin
?Besides this nitpick, i concur with Veen. The post seems to be about exercises/challenges, not FP best practices.
Good point. I guess in C++ numbers aren't objects so you can't do this.
I hope they understand that this is just an exercise. I have seen too often these things being elevated into a religion.
Yeap. I have no hard preference between sin(x) or x.sin, in an OOP context or not, as long as the language is somewhat consistent (e.g., it bothers me that Ruby has some of these functions on the numbers themselves, like 1.23.floor, but others live on Math, like Math.sin(42)).
Every time I type `len(some_list)` in Python, I die a little inside.
Because you can't do the latter post-hoc. You can't add hyperbolic functions by yourself if your standard library didn't anticipate them. Well, in Ruby you can and it's a standard practice to pollute this way classes at random, and in Python you can as well, though it's frowned upon, but certainly you cannot in C++ or Java.
I remember when OOP came up, some people made functions illegal. So instead of
s = sinx(x)
the OOP way was
m = new Math() s = m.sin(x)
And instead of switch statements you had to derive a new class for each case call a virtual function. Very "OOP" but it led to the OOP equivalent of spaghetti code.
Are the functional guys also starting to leave the real world for the sake of being "pure"?