I think the point is, if you write map like this you might as well be using a dynamically typed language in the first place because you're deriving no benefit from the type checker. In fact, you're just using casting to completely circumvent it.
Of course. If the main cornerstone of your project is map it's probably not the greatest idea to use Go, but if you're using Go for other reasons and happen to need a quick map function there's no reason to change languages just because Go doesn't have a standard library implementation
From what I've read/seen, the go blocks are lightweight thread-like processes multiplexed onto a thread pool. You may be correct about using Thread/sleep, ideally I would have used (timeout ...) and then pulled off the channel. However, I didn't want to introduce the concept of channels too early in the post, so I felt Thread/sleep worked as a compromise.
Thread/sleep will block the entire thread. The thread pool could create more threads, but core.async uses a fixed thread-pool, so, yeah, don't use Thread/sleep in a go block. A timeout channel would be the way to go, or, you can use an alternate core.async implementation, which is a (small) part of the Pulsar project: https://groups.google.com/forum/#!topic/clojure/1xxxTti6Vi0 (I'm the main author)
We will have full API and semantic compatibility when version 0.2 is released next week. Pulsar also has cluster distribution and an Erlang-like actor framework.
Because Pulsar uses instrumentation at the bytecode level, you have more freedom within Go blocks. You wouldn't use Thread/sleep in the Pulsar implementation, either, but Strand/sleep will do the job. It detects whether you're in a go block (implemented as a fiber in Pulsar), in which case it suspends the fiber but doesn't block the thread, or within a normal thread, in which case it will simply call Thread/sleep.
Yah, for demo purposes of wanting to show something taking awhile thread/sleep is very convenient. I have no idea, time.sleep in golang might actually block a real thread too. I'm just curious if blocking in a go block could starve your thread pool or if there is some magic being done by the macro to even correct for that?
A fun anecdote is to consider the belief the TDD crowd entertained that, by creating tests for a problem you couldn’t solve, you could somehow evolve a code that passed the tests and therefore solved the problem!
I'm all for a healthy debate of TDD, but the above statement seems ridiculous to me. For me, TDD helps with two main things:
- I specify the behavior I'm adding/changing before I implement it. This helps document the change I believe I'm making.
- I feel more confident when making changes to a large codebase.
TDD works for some and not for others. There are very interesting arguments to be had about the subject. However, can we please stop acting as though TDD advocates view their tests as having psuedo-mystical powers to solve problems automatically?
When we began building our Python library, we looked at both django and sqlalchemy for inspiration in designing our search DSL. Your example seems to closely match the django style. We preferred the sqlalchemy style, but both are solid choices.
We tend to use var when the return type is obvious, but we wanted to be explicit in the examples. Unfortunately, LINQ is not an option for us as we support .NET 2.0.
Your C# and Python predicate examples are quite readable, but in this case they don't work for us. The return type of each of these statements would be true or false, whereas we are building XML requests to be sent to a server to perform the searches. The call to Amount.Between(...) builds an XML node behind the scenes representing the search data.
You mean you support C# 2.0, since var, LINQ, et al run on .Net 2.0 :-P
Doing a full blown Linq Provider would be pretty cool, but would also be very very very time consuming to get right. Expression trees are pretty cool, but you're still dealing with the AST so it gets crazy. There needs to be a Linq Provider framework / library to work at a slightly higher abstraction level.
Ignoring the .NET version problem, not using LINQ probably makes plenty of sense, given that implementing a LINQ solution would be much much more complicated to implement than what you've done. Breaking apart expressions to get to your XML requests would be hard. I also think the proposal above where each criteria is expressed as an individual lamdba is the worst of both worlds in terms of ease of implementation and readability.
I'm the author and I appreciate the insights. I wrote the article about what I consider to be building blocks of metaprogramming. I don't agree at all that eval() is the only piece of JS code that is metaprogramming. I believe that being able to dynamically define methods on objects at runtime is an example of "code that writes code" and hence metaprogrmming. YMMV.
No, that is simply programming with dynamic features. Nearly all modern programming tasks involve this.
In his defense, I'd say that the line between "metaprogramming" and using the features a dynamic language gives you is fuzzy. I'm not sure if I consider changing the semantics of a data type in Lua through its metatable metaprogramming or not, for example.
Generating source code at runtime definitely counts as metaprogramming, but doing that and having to re-parse it is probably the coarsest and most error-prone way. Lisp routes around this by working with ADTs directly, but that forces a lot of other trade-offs in the language design.
Your point? You said that someone should look to these systems as cases of "metaprogramming". Now you say that they are "metaprogrammable". You seem to have a very specific notion of metaprogramming, what exactly would you consider to be a prototypical use of it?