2017-10-11 99 views
0

假设我有一个函数(remove-bad-nodes g)返回这样一个顺序:你如何在REPL中解构?

[updated-g bad-nodes] 

其中updated-g是其糟糕的节点图中移除,并bad-nodes是包含移除的节点的集合。

作为参数传递给函数或let里面,我可以解构这样的:

(let [[g bads] (remove-bad-nodes g)] 
    ...) 

但只定义了局部变量。我怎么能这样做在REPL,这样在未来的命令,我可以参考最新图形为g和删除节点作为bads?浮现在脑海的第一件事情是这样的:

(def [g bads] (remove-bad-nodes g) 

但是,这并不工作,因为def需要它的第一个参数是一个符号。

请注意,我没有问为什么def没有语法像let;有关于此的已有a question。我想知道什么是使用返回“多个值”的函数在REPL中工作的方便实用的方法。如果在正常的Clojure练习中有一定的理由,那么在REPL中不需要解构,因为你做了其他的事情,而解释这可能会提供一个有用的答案。最近我一直在遇到这个问题,这就是我问的原因。通常(但并非总是),这些函数会返回一些更新版本的内容以及其他一些信息。在副作用代码中,函数会修改对象并只返回一个值(在本例中为已删除的节点),但显然这不是Clojurely的方式。

+1

链接问题的答案也会回答你的问题:“如果你愿意,你可以编写一个宏(比如def +)来为你做这件事。” – amalloy

+0

@amalloy你愿意重新打开这个问题吗?这不是非常重要的,因为[你对链接问题的回答](https://stackoverflow.com/a/8198215/1393162)的确给了我一个有用的想法(写一个'def +'宏),但这就是我为什么想的原因这个问题应该单独回答:(1)它确实是关于不同的东西:在REPL中解构。 (2)另一个答案切线提到_解决方案,不一定是唯一的解决方案。也许还有一个我应该使用的其他方法 - 没有'def +'宏。我想你可能有一个很好的理由来称呼宏观! –

+0

你也已经在这个问题上得到了答案,向你展示了你可能称之为“在REPL上解构”的各种东西,主要是实际上REPL没有什么特别之处,只是'let'和“def”表现得很好。我没有看到任何理由重新打开这个问题,但当然你可以自由地编辑它来改善它的范围。 – amalloy

回答

0

没有什么关于解构W/R/T的REPL独特。您的问题的答案基本上与this question相同。我觉得你的选择是:

let

(let [[light burnt just-right] (classify-toasts (make-lots-of-toast))] 
    (prn light burnt just-right)) 

def各个值:

(def result (classify-toasts (make-lots-of-toast))) 
(def light (nth result 0)) 
(def burnt (nth result 1)) 
(def just-right (nth result 2)) 

或者写一个宏来做到这一点def为你工作。

你也可以考虑不同的表现,如果你的函数总是如返回一个3元组/矢量你可以备选地为classify-toasts返回地图:

{:light 1, :burnt 2, :just-right 3} 

然后当你需要这些值中的一个,使用关键字解构地图,无论你需要:

(:light the-map) => 1 
0

观察:

user=> (def results [1 2 3]) 
#'user/results 
user=> (let [[light burnt just-right] results] (def light light) (def burnt burnt) (def just-right just-right)) 
#'user/just-right 
user=> light 
1 
user=> burnt 
2 
user=> just-right 
3 
1

我的思维方式与在REPL这样的功能的工作仅仅是不def你的中间结果,除非他们是特别有趣;有趣,足够的中间结果它不是一个大麻烦要么def他们一个名称,或者写一个解构形式内的多个def秒。

例如,而不是

(def [x y] (foo)) 
(def [a b] (bar x y)) 

你可以写

(let [[x y] (foo), 
     [x' y'] (bar x y)]) 
    (def a x') ; or maybe leave this out if `a` isn't that interesting 
    (def b y')) 

这方面的一个很好的副作用是,你写的,而在REPL玩耍代码看起来更加类似于你有一天会将代码添加到源文件中,在那里你一定不会重复某些事情,而是解构它们,将它们传递给函数,等等。将您在repl学到的信息调整为真正的程序会更容易。