I undertook an interview last week in which I learnt a few things about python I didn’t know about (or rather realise how they could be used), first up and the content of this question is the use of or for the purposes of branch control.
So, for example, if we run:
def f():
# do something. I'd use ... but that's actually a python object.
def g():
# something else.
f() or g()
Then if f() evaluates to some true condition then that value is returned, if not, g() is evaluated and whatever value it produces is returned, whether true or false. This gives us the ability to implement an if statement using or keywords.
We can also use and such that f() and g() will return the value of g() if f() is true and the value of f() if g() is false.
I am told that this (the use of or for branch control) is a common thing in languages such as lisp (hence the lisp tag). I’m currently following SICP learning Scheme, so I can see that (or (f x) (g x)) would return the value of (g x) assuming (f x) is #f.
I’m confused as to whether there is any advantage of this technique. It clearly achieves branch control but to me the built in keywords seem more self-explanatory.
I’m also confused as to whether or not this is “functional”? My understanding of pure functional programming is that you use constructs like this (an example from my recent erlang experiments):
makeeven(N,1) -> N+1;
makeeven(N,0) -> N;
makeeven(N) -> makeeven(N,N rem 2).
Or a better, more complicated example using template meta-programming in C++ (discovered via cpp-next.com). My thought process is that one aspect of functional programming boils down the use of piecewise defined functions in code for branch control (and if you can manage it, tail recursion).
So, my questions:
- Is this “functional”? It appears that way and my interviewers said they had backgrounds in functional programming, but it didn’t match what I thought was functional. I see no reason why you couldn’t have a logical operator as part of a function – it seems to lend itself nicely to the concept of higher order functions. I just hadn’t thought that the use of logical operators was how functional programmers achieved branch control. Right? Wrong? I can see that circuits use logic gates for branch control so I guess this is a similar (related) concept?
- Is there some advantage to using this technique? Is it just language conciseness/a syntax issue, or are there implications in terms of building an interpreter to using this construct?
- Are there any use cases for this technique? Or is it not used very often? Is it used at all? As a self-taught guy I’d never seen it before although that in itself isn’t necessarily surprising.
I apologise for jumping over so many languages; I’m simply trying to tie together my understanding across them. Feel free to answer in any language mentioned. I also apologise if I’ve misunderstood any definitions or am missing something vital here, I’ve never formally studied computer science.
Your interviewers must have had a “functional background” way back. It used to be common to write
but in CL and in Scheme implementation that support it, it is much better written with
unless. Same goes forandvswhen.So, to be more concrete — it’s not more functional (and in fact the common use of these things was for one-sided conditionals, which are not functional to begin with); there is no advantage (which becomes very obvious in these languages when you know that things are implemented as macros anyway — for example, most
orandandimplementations expand to anif); and any possible use cases should usewhenandunlessif you have them in your implementation, otherwise it’s better to define them as macros than to not use them.Oh, and you could use a combination of them instead of a two sided
if, but that would be obfuscatingly ugly.