Hacker News new | ask | show | jobs
by Gonsalu 5694 days ago
FAST? It's still .NET. Regarding you example, I'd much rather write

  value = dict.get('foo', 'default')
in IronPython.
4 comments

I'm not familiar with python - does it have some magic global sentinel value to indicate "not found"? Or how do you handle that case with that 1 line of code?

Secondly, saying "it's still .NET" is similar to saying "it's still x64". The F# compiler does a lot of transforms on code that the C# compiler does not. In some cases, this can result in better IL and better JIT'd code. Also, having inlining support at the compiler level can be very handy sometimes.

> I'm not familiar with python - does it have some magic global sentinel value to indicate "not found"?

No, it has a different method for failable search. The purpose of `get` is specifically to handle "provide a default value in case the key is not found".

> Or how do you handle that case with that 1 line of code?

dict[key]

You can also use defaultdict[0], or define the __missing__() method[1] yourself on a dictionary you receive from someone else's code. In either of these cases the "not found" value will be whatever you decide it should be.

[0]: http://docs.python.org/library/collections.html#collections.... [1]: http://docs.python.org/library/stdtypes.html#dict

Yes, good points MichaelGG, one of the really nice things about the F# compiler is that it can inline higher order functions, so if you pass a function to another it may create a custom piece of code with your passed function inlined. I wasn't sure if you were referring to C style inline support, which C# does have (in the .NET JIT). Like C the inlining in F# is just a suggestion to the compiler.

So you can write code that is optimal from a design point of view (abstractions, etc) and the compiler will turn it into optimal code from a performance point of view.

See http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-burrow... for a much better explanation.

I don't think that F#'s inline is just a suggestion. Hat types (^a) aka statically resolved type variables, require inline methods to actually be inline. Same way you can't have inlined recursive functions.
You can nest a recursive function inside a non-recursive one and inline that.

  namespace Org.DictionaryExtensions =
    type Dictionary<'T> with
     member x.get(key,defaultValue) = 
       match x.TryGetValue(key) with
       | (true,val) -> val
       | (false,_) -> defaultValue
There fixed that for you, now you can do, dict.get("foo","defaultvalue") in whatever CLR language you like. :)

As for fast and knocking .NET you're not seriously suggesting python are you? Runtime method lookup is not exactly what I think when thinking fast.

I wasn't knocking .NET; I had the idea that coding something in C# or F# would result in the same IL output, which, after reading MichaelGG's reply, I realized was completely wrong...

Regarding Python speed, I know it's pretty slow, especially the IronPython implementation.

Upvoted because that's good code reuse in the scenario that you only want to store a default value, and I can see why you replied to the commenter with it. It doesn't necessarily work so well in the scenario where you want to perform some operation if there isn't a value. Or if default needs to be computed. I'm assuming that the idiomatic way of doing this in python would be:

try: value = dict['foo'] except KeyNotFound: value = do_something_interesting() dict['foo'] = value

If you could pass a function in as a default of course this point is moot!

See collections.defaultdict in the standard library -- http://docs.python.org/library/collections.html#collections....
> It doesn't necessarily work so well in the scenario where you want to perform some operation if there isn't a value.

No, but that's not what the example he replied to does.

CL

  (setf value (gethash "foo" dict "default"))