Re: maintainability, DSLs, declarative APIs, etc.
On Friday, 15 November 2013 13:12:29 UTC-7, Jay Fields wrote: Better to have the ability when you desire it, than not to have it - if you're willing to put up with other people (ab)using that power at times. +1, with one caveat. If you have a rule of thumb like introduce an abstraction when you have repeated yourself three times, the bar for introducing meta-programming abstractions should be set much higher than three. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
To me macros DSLs are just an instance/extension of the DRY principle and not that much different to using functions (albeit with more syntactic freedom, e.g. by supplying a body expression to be wrapped or transformed into something more complex). Of course there's the potential loss of control understanding when using 3rd party macros, but in Clojure the use of library macros is often hardly enforced without also having a purely functional way as alternative. I think the stronger reliance on certain naming conventions (e.g. in RoR) or the type specific overriding of operators in C++ has much more of a magical/mysterious element to it than most of the CLJ macros I've been using thus far. Last but not least, since most libs are open source, what stops you from studying a specific macro/DSL? My 2p... On 15 Nov 2013 19:51, Brian Craft craft.br...@gmail.com wrote: Pulling this from another thread: On Nov 14, 2013, at 2:28 AM, Sean Johnson bel...@acm.org wrote: The magic of meta-programming (Ruby) vs. magic of macros (Clojure) vs. no magic (Python). This probably comes down to personal preference, and so is a potential benefit of any of them, depending on your preference, but it's a significant difference, so it's worth pointing out. By magic I just mean when the system seems to be more doing something much more powerful than you can readily see just by looking at the code. A simple few lines of code are doing all these wondrous things that aren't spelled out completely in the code (unless you peek under the covers and can understand the black arts that lie there). In Ruby/Rails this is the result of a lot of metaprogramming happening, based on conventions (that must be learned). In Clojure this happens through macros that implement powerful DSLs. In Python, it doesn't happen nearly as much. Code tends to be more transparent. This description of ruby, clojure, and python very much matches my experience (though with ruby I'm relying on the accounts of other developers that I know, since I haven't personally used ruby). Why are black arts and opaque code desirable? It's almost a tautology that these things are unmaintainable: you can't maintain code if you can't readily understand it, e.g. if it depends on black arts, or is not transparent. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
I've worked extensively in Java, Ruby, and Clojure, so I have plenty of experience with having and not having meta-programming and macros. In my opinion meta-programming and macros are not black art, they are simply part of the language. If someone chooses to do something that isn't easy to understand, that's not the fault of the language, it's the fault of the programmer. (this is the royal You, not Brian) Your language choice should probably factor in your desire to dig into metaprogramming or macros. You don't need to use those features of the language in your own code, but you'll surely run into both using someone else's framework or library. If you prefer not to deal with the complexities that can arise from having those features available, not using Ruby or Clojure is probably a good choice. Conversely, if you want the power of metaprogramming and macros, and are willing to learn them deeply enough that you can deal with some poorly written metaprogramming or macros, then you should prefer Ruby or Clojure. Better to have the ability when you desire it, than not to have it - if you're willing to put up with other people (ab)using that power at times. It's a balance, and I strongly believe that people program in many different ways. (among other tradeoffs) You can have a powerful IDE and a ton of boiler plate, explicit code, or you can have little refactoring support and the ability to eliminate the boiler plate code; you have to chose which you value more. You also need to know that the choice you make will eliminate working with some people - those that choose the other way. Neither group of people will be good or bad, both will have great and terrible programmers who simply prefer to program in differing ways. On Fri, Nov 15, 2013 at 2:51 PM, Brian Craft craft.br...@gmail.com wrote: Pulling this from another thread: On Nov 14, 2013, at 2:28 AM, Sean Johnson bel...@acm.org wrote: The magic of meta-programming (Ruby) vs. magic of macros (Clojure) vs. no magic (Python). This probably comes down to personal preference, and so is a potential benefit of any of them, depending on your preference, but it's a significant difference, so it's worth pointing out. By magic I just mean when the system seems to be more doing something much more powerful than you can readily see just by looking at the code. A simple few lines of code are doing all these wondrous things that aren't spelled out completely in the code (unless you peek under the covers and can understand the black arts that lie there). In Ruby/Rails this is the result of a lot of metaprogramming happening, based on conventions (that must be learned). In Clojure this happens through macros that implement powerful DSLs. In Python, it doesn't happen nearly as much. Code tends to be more transparent. This description of ruby, clojure, and python very much matches my experience (though with ruby I'm relying on the accounts of other developers that I know, since I haven't personally used ruby). Why are black arts and opaque code desirable? It's almost a tautology that these things are unmaintainable: you can't maintain code if you can't readily understand it, e.g. if it depends on black arts, or is not transparent. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
On Friday, November 15, 2013 12:10:59 PM UTC-8, Karsten Schmidt wrote: To me macros DSLs are just an instance/extension of the DRY principle and not that much different to using functions (albeit with more syntactic freedom, e.g. by supplying a body expression to be wrapped or transformed into something more complex). Of course there's the potential loss of control understanding when using 3rd party macros, but in Clojure the use of library macros is often hardly enforced without also having a purely functional way as alternative. I think the stronger reliance on certain naming conventions (e.g. in RoR) or the type specific overriding of operators in C++ has much more of a magical/mysterious element to it than most of the CLJ macros I've been using thus far. Last but not least, since most libs are open source, what stops you from studying a specific macro/DSL? Thanks for your perspective. Regarding the last question, it's a matter of scaling. Often in production code you have to be in and out of an unfamiliar piece of code in a few hours. You can't stop to study an unfamiliar DSL for a couple days. I've heard people doing contract work in ruby swearing when they encounter another DSL: it kills their productivity. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
On Fri, Nov 15, 2013 at 3:30 PM, Brian Craft craft.br...@gmail.com wrote: I've heard people doing contract work in ruby swearing when they encounter another DSL: it kills their productivity. those same people wouldn't have Ruby contracting work if it weren't for metaprogramming... -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
The first rule of macro club is Don't write macros. Macros are powerful, but they should be considered the last avenue of attack. Often macros are a slim wrapper around an API made out of functions, and there just to provide some syntax sugar. Libraries that use macros more extensively, like core.logic, or the go form in core.async, are relatively rare, and cover the cases where nothing else but macros are powerful enough to implement the desired functionality. Instead, it's far better to start with a data-driven approach. A data structure is always preferable over an API, and an API is always preferable over a DSL. This approach can be seen in Datomic, which uses data structures to represent queries and commands, or Ring, where data structures are used to represent HTTP requests and responses. Clojure heavily emphasises data, far more than most other languages, and certainly more than OOP. - James On 15 November 2013 19:51, Brian Craft craft.br...@gmail.com wrote: Pulling this from another thread: On Nov 14, 2013, at 2:28 AM, Sean Johnson bel...@acm.org wrote: The magic of meta-programming (Ruby) vs. magic of macros (Clojure) vs. no magic (Python). This probably comes down to personal preference, and so is a potential benefit of any of them, depending on your preference, but it's a significant difference, so it's worth pointing out. By magic I just mean when the system seems to be more doing something much more powerful than you can readily see just by looking at the code. A simple few lines of code are doing all these wondrous things that aren't spelled out completely in the code (unless you peek under the covers and can understand the black arts that lie there). In Ruby/Rails this is the result of a lot of metaprogramming happening, based on conventions (that must be learned). In Clojure this happens through macros that implement powerful DSLs. In Python, it doesn't happen nearly as much. Code tends to be more transparent. This description of ruby, clojure, and python very much matches my experience (though with ruby I'm relying on the accounts of other developers that I know, since I haven't personally used ruby). Why are black arts and opaque code desirable? It's almost a tautology that these things are unmaintainable: you can't maintain code if you can't readily understand it, e.g. if it depends on black arts, or is not transparent. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: maintainability, DSLs, declarative APIs, etc.
One more point that no one has emphasized: Lisps allow code to write code. Sometimes the way to provide an abstraction or generalization of a pattern is by writing a code-writer. Macros provide a convenient way of using that capability. (On a project years ago, for every Java class of kind X, we needed a corresponding Java class of kind Y. There were many X classes, so I ended up writing a Perl script to construct Y source files from X source files. It was much easier to do that with Perl than to write a Java code-translator. For an analogous problem with Clojure code, it would be even easier use Clojure to generate the new code.) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.