TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Shake: Every Program Can Be a Clojure Function

79 pointsby sunngover 12 years ago

12 comments

btillyover 12 years ago
Shake draws inspiration from Python's sh. Which looks to me like a port of <a href="http://perldoc.perl.org/Shell.html" rel="nofollow">http://perldoc.perl.org/Shell.html</a>. However after experience, that original version now comes with important warnings about things like metacharacter quoting not being able to be done in a portable and safe way.<p>It is easy to get things 95% right, and I am sure that Shake does that. But think twice before using it for production programs, <i>particularly</i> if there is any possibility of it encountering untrusted input.
draegtunover 12 years ago
<i>&#62; We will have a beautiful DSL so you don’t have to quote arguments as string...</i><p>If i'm using Perl's <i>Shell.pm</i> (as mentioned elsewhere here by <i>btilly</i>) and wanted to avoid quoting arguments then I could do:<p><pre><code> use 5.016; use warnings; use Shell (); use PerlX::QuoteOperator ls =&#62; { -emulate =&#62; 'qq', -with =&#62; sub ($) { Shell::ls($_[0]) }, }; use PerlX::QuoteOperator uname =&#62; { -emulate =&#62; 'qq', -with =&#62; sub ($) { Shell::uname($_[0]) }, }; use PerlX::QuoteOperator ip =&#62; { -emulate =&#62; 'qq', -with =&#62; sub ($) { Shell::ip($_[0]) }, }; # and then... ls(); uname(-a); ip(-4 addr); </code></pre> But this seems to be an overkill because I could just use Perl's backticks (<a href="http://perldoc.perl.org/perlop.html#Quote-Like-Operators" rel="nofollow">http://perldoc.perl.org/perlop.html#Quote-Like-Operators</a>)...<p><pre><code> `ls`; `uname -a`; `ip -4 addr`; </code></pre> And it works with variables...<p><pre><code> my $x = "/usr/local/"; my $files = `ls -l $x`; </code></pre> and piping...<p><pre><code> my $perl_files = `ls | grep .pl`; </code></pre> <i>Shell.pm</i> also works with variables &#38; piping but I think that backticks are probably Perl's best <i>DSL</i> for dealing (easily) with shell stuff :)
jcromartieover 12 years ago
This is a really bad idea. It's not even close to useful right now. For instance, you can't use variables in your shell invocation, so this doesn't work:<p><pre><code> (let [x "/usr/local"] (ls -l x)) </code></pre> And it clobbers so many things in the core namespace when 'use'd.<p>Good luck.
评论 #4554098 未加载
cs702over 12 years ago
All these efforts to provide pretty &#38; convenient interfaces to arbitrary executables strike me as being useful only for people who want a powerful REPL as their command-line prompt and/or would rather use Clojure or Python (or whatever other language) for mundane tasks that would otherwise normally be done with throwaway shell scripts. Outside of these limited use cases, I'm not sure this sort of thing is a good idea.
duelin_markersover 12 years ago
Creating this was probably fun and a good learning experience, but I wouldn't recommend trying to push it beyond that point. The problem Shake solves doesn't call for the sort of DSL that uses macros to make Clojure code act like something other than Clojure code.<p>I'd rather have something like <a href="https://github.com/clojure/tools.cli" rel="nofollow">https://github.com/clojure/tools.cli</a> but in reverse: a library for building, manipulating, and running command lines and interacting with the results ... maybe something that supports setting up mappings so that external programs can be exposed as Clojure fns with "Clojuresque" arguments "--rather" "than" "--arrays-of" "strings".
评论 #4555638 未加载
Tuna-Fishover 12 years ago
That's both wonderful and scary. I think the UI of it needs work -- if you want to treat all shell commands as functions, they imho should just return their outputs by default. (Potentially as a lazy list of lines?)<p>Also, I think that path should not be passed in as an environment variable, but in Clojure somehow. There's no reason for a program to pollute a global namespace with it's internal details.
评论 #4553374 未加载
评论 #4553428 未加载
评论 #4553499 未加载
hugoduncanover 12 years ago
Sounds very much like pallet's stevedore.<p><a href="http://palletops.com/doc/reference/script/" rel="nofollow">http://palletops.com/doc/reference/script/</a> <a href="https://github.com/pallet/stevedore" rel="nofollow">https://github.com/pallet/stevedore</a>
vsipuliover 12 years ago
This was already pioneered by Olin Shivers' SCSH (Scheme Shell). See the process notation chapter in the SCSH Reference Manual: <a href="http://www.scsh.net/docu/html/man-Z-H-3.html#node_chap_2" rel="nofollow">http://www.scsh.net/docu/html/man-Z-H-3.html#node_chap_2</a>. Wish the SCSH project would come alive again: <a href="https://github.com/scheme/scsh" rel="nofollow">https://github.com/scheme/scsh</a>.
Kototamaover 12 years ago
That's great. Next step is implementing piping :-)
评论 #4553310 未加载
mattdeboardover 12 years ago
This is actually pretty neat, specifically the part about indexing the executables available in your path and turning them into macros. I was underwhelmed at first because I thought you manually implemented each program.<p>I can't really imagine a use case for this for me (bash! But with parens!) but still very neat idea and cool execution.
评论 #4553409 未加载
dschiptsovover 12 years ago
A function? Really? Without side effects?)
sunngover 12 years ago
You can set environment variable SHAKE_PATH to specify path that you want to initialize.