Giter Club home page Giter Club logo

debux's People

Contributors

gnl avatar lucywang000 avatar marksto avatar philoskim avatar royalaid avatar victorb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

debux's Issues

Cannot use first-class dbgn fn within macro

Version: [philoskim/debux "0.4.11"]

Here's the simplest example:

(dbgn
  (defn glug []
    ))

(defmacro bar [data]
  `(do
     ~(get data ::key glug)))

(defn -main []
  (bar {}))

The error:

Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(core.clj:13:1)
	at clojure.lang.Compiler$DefExpr.eval(Compiler.java:470)
	at clojure.lang.Compiler.eval(Compiler.java:7067)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at user$eval3111$fn__3115.invoke(form-init1748171861957467243.clj:1)
	at user$eval3111.invokeStatic(form-init1748171861957467243.clj:1)
	at user$eval3111.invoke(form-init1748171861957467243.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7052)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
	at clojure.main$load_script.invokeStatic(main.clj:278)
	at clojure.main$init_opt.invokeStatic(main.clj:280)
	at clojure.main$init_opt.invoke(main.clj:280)
	at clojure.main$initialize.invokeStatic(main.clj:311)
	at clojure.main$null_opt.invokeStatic(main.clj:345)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ExceptionInInitializerError
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at clojure.lang.Compiler$ObjExpr.eval(Compiler.java:4989)
	at clojure.lang.Compiler$DefExpr.eval(Compiler.java:457)
	... 42 more
Caused by: java.lang.IllegalArgumentException: No matching ctor found for class debux_meta.core$eval6680$glug__6681
	at clojure.lang.Reflector.invokeConstructor(Reflector.java:163)
	at clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1303)
	at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:843)
	at clojure.lang.LispReader.read(LispReader.java:275)
	at clojure.lang.LispReader.read(LispReader.java:206)
	at clojure.lang.LispReader.read(LispReader.java:195)
	at clojure.lang.RT.readString(RT.java:1871)
	at clojure.lang.RT.readString(RT.java:1866)
	at debux_meta.core$_main.<clinit>(core.clj:13)
	... 49 more

No namespace: cljs.core found

I tried following things in an plain vanilla project for verification. Have I missed anything?

Try and exceptions

$ lein repl
user=> (use 'debux.core)
CompilerException java.lang.Exception: No namespace: cljs.core found, compiling:(debux/cs/macro_types.cljc:5:1)


Environments and dependencies
Leiningen: 2.8.1
JVM: 1.8, 64bit

:dependencies [[org.clojure/clojure "1.8.0"]
               [org.clojure/clojurescript "1.9.854"]
               [philoskim/debux "0.4.6"]]

debux mishandles letfn + try + loop

Version [philoskim/debux "0.4.10"]

Oddly, it appears to be this particular combination which really upsets debux. The fn doesn't need to be called at all; an exception is thrown when compiling it:

(dbgn
  (defn bar []
    (letfn [(foo []
              (try
                nil
                (catch Exception e
                  nil)))]
      (loop [i 0]
        (recur (inc i))))))

The exception:

Exception in thread "main" java.lang.NullPointerException, compiling:(debux_meta/core.clj:5:1)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7010)
	at clojure.lang.Compiler.analyze(Compiler.java:6773)
	at clojure.lang.Compiler.analyze(Compiler.java:6729)
	at clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2822)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
	at clojure.lang.Compiler.analyze(Compiler.java:6773)
	at clojure.lang.Compiler.analyze(Compiler.java:6729)
	at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
	at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5460)
	at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4022)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7001)
	at clojure.lang.Compiler.analyze(Compiler.java:6773)
	at clojure.lang.Compiler.eval(Compiler.java:7059)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at user$eval3111$fn__3115.invoke(form-init8000152408779894085.clj:1)
	at user$eval3111.invokeStatic(form-init8000152408779894085.clj:1)
	at user$eval3111.invoke(form-init8000152408779894085.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7052)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
	at clojure.main$load_script.invokeStatic(main.clj:278)
	at clojure.main$init_opt.invokeStatic(main.clj:280)
	at clojure.main$init_opt.invoke(main.clj:280)
	at clojure.main$initialize.invokeStatic(main.clj:311)
	at clojure.main$null_opt.invokeStatic(main.clj:345)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at clojure.lang.Namespace.find(Namespace.java:188)
	at clojure.core$find_ns.invokeStatic(core.clj:4096)
	at clojure.core$the_ns.invokeStatic(core.clj:4126)
	at clojure.core$ns_name.invokeStatic(core.clj:4130)
	at clojure.core$ns_name.invoke(core.clj:4130)
	at debux.common.util$var__GT_symbol.invokeStatic(util.cljc:112)
	at debux.common.util$var__GT_symbol.invoke(util.cljc:110)
	at debux.common.util$ns_symbol_for_clj.invokeStatic(util.cljc:119)
	at debux.common.util$ns_symbol_for_clj.invoke(util.cljc:117)
	at debux.common.util$ns_symbol.invokeStatic(util.cljc:140)
	at debux.common.util$ns_symbol.doInvoke(util.cljc:136)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at debux.common.skip$insert_o_skip_for_recur.invokeStatic(skip.cljc:190)
	at debux.common.skip$insert_o_skip_for_recur.doInvoke(skip.cljc:180)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at debux.dbgn$dbgn.invokeStatic(dbgn.clj:298)
	at debux.dbgn$dbgn.doInvoke(dbgn.clj:286)
	at clojure.lang.RestFn.applyTo(RestFn.java:146)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.lang.Compiler.macroexpand1(Compiler.java:6912)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6989)
	... 53 more

debux mishandles defn's attribute map

Hey there! As per the docs, defn allows for attribute maps before the arities, as well as after. debux ends up wrapping these guys in debux.dbgn/d, which causes Clojure to choke. Here's the simplest test case showing the issue:

(dbgn
  (defn identity'
    {:private true}
    [x]
    x))

When trying to hook dbgn into an existing macro, which is taking advantage of these attribute maps, I've hit a wall. Hopefully this is something you're willing to support!

Can't init clojurescript in clojure-only project

I have a plain clojure project (no clojurescript), when I use debux and require core namespace in REPL i get exception

CompilerException java.io.FileNotFoundException: Could not locate cljs/analyzer/api__init.class or cljs/analyzer/api.clj on classpath., compiling:(debux/common/util.cljc)

Probably this caused by init of [cljs.analyzer.api :as ana] which is not in classpath.
Is there a way to disable clojurescript and make it work for clojure only?

P.S. Adding clojurescript deps looks like short term fix, but would be good to avoid unnecessary deps

Java 10 Exception

Hello.

It is seems that debux will not run on JVM 10.
I want to use debux 0.5.0 and my deps.edn look like this:

:xb {:jvm-opts ["--add-modules" "java.xml.bind"]}
:debug-tools {:extra-deps {vvvvalvalval/scope-capture {:mvn/version "0.3.1"}
philoskim/debux {:mvn/version "0.5.0"}
spyscope {:mvn/version "0.1.7-SNAPSHOT"}
com.bhauman/spell-spec {:mvn/version "0.1.1"}}

I run REPL:
clojure -R:debug-tools:xb -r

nREPL 0.4.5
Clojure 1.10.0-alpha7
Java HotSpot(TM) 64-Bit Server VM 10.0.2+13
user=> (use 'debux.core)
Syntax error compiling at (cljs/util.cljc:1:1).
Cause: javax.xml.bind.DatatypeConverter

user=> *e
#error {
:cause "javax.xml.bind.DatatypeConverter"
:via
[{:type clojure.lang.Compiler$CompilerException
:message "Syntax error compiling at (cljs/util.cljc:1:1)."
:data #:clojure.error{:line 1, :column 1, :phase :compile, :source "cljs/util.cljc"}
:at [clojure.lang.Compiler load "Compiler.java" 7624]}
{:type java.lang.ClassNotFoundException
:message "javax.xml.bind.DatatypeConverter"
:at [java.net.URLClassLoader findClass "URLClassLoader.java" 466]}]
:trace
[[java.net.URLClassLoader findClass "URLClassLoader.java" 466]
[clojure.lang.DynamicClassLoader findClass "DynamicClassLoader.java" 69]
[java.lang.ClassLoader loadClass "ClassLoader.java" 566]
[clojure.lang.DynamicClassLoader loadClass "DynamicClassLoader.java" 77]
[java.lang.ClassLoader loadClass "ClassLoader.java" 499]
[java.lang.Class forName0 "Class.java" -2]
[java.lang.Class forName "Class.java" 374]
[clojure.lang.RT classForName "RT.java" 2204]
[clojure.lang.RT classForNameNonLoading "RT.java" 2217]
[cljs.util$eval182$loading__6539__auto____183 invoke "util.cljc" 9]
[cljs.util$eval182 invokeStatic "util.cljc" 9]
[cljs.util$eval182 invoke "util.cljc" 9]
[clojure.lang.Compiler eval "Compiler.java" 7160]
[clojure.lang.Compiler eval "Compiler.java" 7149]
[clojure.lang.Compiler load "Compiler.java" 7612]
[clojure.lang.RT loadResourceScript "RT.java" 379]
[clojure.lang.RT loadResourceScript "RT.java" 370]
[clojure.lang.RT load "RT.java" 460]
[clojure.lang.RT load "RT.java" 426]
[clojure.core$load$fn__6653 invoke "core.clj" 6071]
[clojure.core$load invokeStatic "core.clj" 6070]
[clojure.core$load doInvoke "core.clj" 6054]
[clojure.lang.RestFn invoke "RestFn.java" 408]
[clojure.core$load_one invokeStatic "core.clj" 5873]
[clojure.core$load_one invoke "core.clj" 5868]
[clojure.core$load_lib$fn__6598 invoke "core.clj" 5913]
[clojure.core$load_lib invokeStatic "core.clj" 5912]
[clojure.core$load_lib doInvoke "core.clj" 5893]
[clojure.lang.RestFn applyTo "RestFn.java" 142]
[clojure.core$apply invokeStatic "core.clj" 659]
[clojure.core$load_libs invokeStatic "core.clj" 5950]
[clojure.core$load_libs doInvoke "core.clj" 5934]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.core$apply invokeStatic "core.clj" 659]
[clojure.core$require invokeStatic "core.clj" 5972]
[clojure.core$require doInvoke "core.clj" 5972]
[clojure.lang.RestFn invoke "RestFn.java" 436]
....skipped.......

debux mishandles if-let

Version: [philoskim/debux "0.4.9"]

Here's the simplest test case:

(dbgn
  (defn foo []
    (if-let [user-json nil]
      ::then
      ::else)))

The error:

Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/if-let did not conform to spec:
In: [3] val: (:debux-meta.core/else) fails at: [:args] predicate: (cat :bindings (and vector? :clojure.core.specs.alpha/binding) :then any? :else (? any?)),  Extra input
 #:clojure.spec.alpha{:problems [{:path [:args], :reason "Extra input", :pred (clojure.spec.alpha/cat :bindings (clojure.spec.alpha/and clojure.core/vector? :clojure.core.specs.alpha/binding) :then clojure.core/any? :else (clojure.spec.alpha/? clojure.core/any?)), :val (:debux-meta.core/else), :via [], :in [3]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x56554365 "clojure.spec.alpha$regex_spec_impl$reify__2436@56554365"], :value ([user-json nil] (debux.common.util/insert-blank-line) :debux-meta.core/then :debux-meta.core/else), :args ([user-json nil] (debux.common.util/insert-blank-line) :debux-meta.core/then :debux-meta.core/else)}, compiling:(debux_meta/core.clj:5:1)

EDIT: Looks like if-some fails as well.

Using the dbg-> macro in dbgn

Hi there, firstly thanks heaps for creating this library, it is very useful. I've been looking at the output of dbg and dbgn and wondered if it would be possible for dbgn to use the special-casing approach in dbg where it wraps ->, ->>, comp and let?

I've taken a look through the code and I get the general approach, but wondered if there were some subtleties which meant that the approaches of dbg and dbgn wouldn't work together?

Dev vs production builds?

This looks fantastic, thanks!

But, could you add some tips (to the examples or readme) of best practices to pull in this code only in dev builds?

Feature request: use custom object printer

First, thank you for this wonderful library. I use it constantly.

I have some records for which I've defined custom printing functions, and I'd like to be able to see this version in my debux output. I'd like the ability to prevent certain objects from being turned into maps by the debux printer.

I should add that I'd like this to work even when the objects are nested inside other objects. I tried the :print option, and while I think I could eventually get that to work, it would require a tree traversal to find all of the objects I want to print using my custom printer.

Avoid debux specific forms coming back in the output?

Hi, is there any way to avoid having the output include internal debux forms like wrapping (clojure.core/binding [debux.common.util/*indent-level* (clojure.core/inc debux.common.util/*indent-level*)] (clojure.core/reset! (:evals +debux-dbg-opts+) {}) (or extra do blocks) on to submitted sub-forms, etc - and just returning the orignals? Thanks!

:if with nil

Hi,

Thanks for your super userful library!

Is it expected behavior that the ... :if nil ... modifier will always evaluate to true, thereby causing the logging/breaking to effectively occur? I would expect that it should have similar behaviour as ... :if false ...

Use of undeclared Var debux.common.util/clojure

When compiling with shadow-cljs I get the following warning from the Google Closure Compiler:

------ WARNING #1 - :undeclared-var --------------------------------------------
 Resource: debux/common/util.cljc:77:14
--------------------------------------------------------------------------------
  74 |   (boolean (:ns env)))
  75 |
  76 | (defn lazy-seq? [coll]
  77 |   (instance? clojure.lang.IPending coll))
--------------------^-----------------------------------------------------------
 Use of undeclared Var debux.common.util/clojure
--------------------------------------------------------------------------------
  78 |
  79 | (defn replace-& [v]
  80 |   (walk/postwalk-replace {'& ''&} v))
  81 |
--------------------------------------------------------------------------------

I'm not 100% sure, but the right approach would probably be to check against this, right? https://github.com/clojure/clojurescript/blob/75e4e528f84a38b7bb9741a498f153457182a057/src/main/cljs/cljs/core.cljs#L3412

Request to return local vars

I found a useful function in the Postmortem that provides the local variables of a function. It's really useful for trying to understand the local context of the function. Would you consider adding a feature to debux?

For example, something like this:

(let [i 10]
    (* 2 (dbg (+ i 5) :locals ))

{:ns user, :line 1}
    dbg: (+ 10 5) :locals {:i 10} =>
    |   15
    30

(dbgn :locals (defn stats [fname [height weight] ]
            (let [i 10]
            (println fname "is" height))))

(stats "Bob" [178 68])

| fname =>
|   "Bob"
| height =>
|   178
Bob is 178
| (println fname "is" height) =>
|   nil
| (let [i 10] (debux.common.util/insert-blank-line) (println fname "is"  ... =>
|   nil
nil
| :locals {name "Bob", height 178,  weight 68, i 10}
     

A new option called :locals provides any local vars.

In Postmortem there's a specific function called debug, see the link for an example. Hash-meta has played with some interesting ideas and its implementation does this:

{:locals {}, :result 23, :form (+ 3 (* 4 5))}

The only way I could figure out how to do this with debux at the moment was to specifically call the vars in a dbg such as (dbg [fname height weight i])

Feature request: optionally return results instead of printing

I've been thinking that it would be great to be able to get the debug results so that it is possible to show them in different UI's, similar to re-frame-debux, but without the re-frame dependency. Other use cases would be logging or piping into REBL, reveal or portal.
I've already started a prototype to play around with designs for the interface. If you are interested in the feature I'll fork and push my changes.

Request to make output lines in REPL more concise with fewer lines

This is a very trivial request because it's solely about how the debug output looks. It may be solely a question of personal preference.

I have been trying out a few debugging tools like Hashp, Spyscope and Tupelo

What I notice with the output of debux, is that it's taking a lot more lines in the REPL.

  1. Add output of the expression into the expression line
    Debux separates out the form and the output. In Spyscope you would do this:
user=> (take 20 (repeat (spyx :dbug (+ 1 2 3))))
    :dbg (+ 1 2 3) => 6
    (6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)

In Debux:

user=> (take 20 (repeat (dbg (+ 1 2 3))))

    {:ns user, :line 1}
    dbg: (+ 1 2 3) =>
    |   6
    (6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)

The value of the form (+ 1 2 3) is put on a new line and a | put ahead of it. I find this visually a bit confusing, I expect the output to be after the =>.

When you do it with debugn on something longer it becomes very spread out. This time using hashp (I had problems with Spyscope):

    user=> (inc #p (* 2 #p (+ 3 #p (* 4 5))))
    #p[user/eval9305:1] (* 4 5) => 20
    #p[user/eval9305:1] (+ 3 (* 4 5)) => 23
    #p[user/eval9305:1] (* 2 (+ 3 (* 4 5))) => 46
    47

Then with debux:

    ;; Example 2: we want the value of each step
    (dbgn (inc (* 2 (+ 3 (* 4 5)))))

    {:ns user, :line 1}
    dbgn: (inc (* 2 (+ 3 (* 4 5)))) =>
    | (* 4 5) =>
    |   20
    | (+ 3 (* 4 5)) =>
    |   23
    | (* 2 (+ 3 (* 4 5))) =>
    |   46
    | (inc (* 2 (+ 3 (* 4 5)))) =>
    |   47
    47

I would like dbg and dbgn to put the value of the form after the arrow (=>) on the same line. So this would become:

(dbgn (inc (* 2 (+ 3 (* 4 5)))))

    {:ns user, :line 1}
    dbgn: (inc (* 2 (+ 3 (* 4 5)))) =>
    | (* 4 5) => 20
    | (+ 3 (* 4 5)) => 23
    | (* 2 (+ 3 (* 4 5))) => 46
    | (inc (* 2 (+ 3 (* 4 5)))) => 47
    47

I find this view easier to understand the steps and see the output clearly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.