4 ms·
This snippet doesn't look right macro nullthrows(sourceCodeSnippet) { return code` const result = ${sourceCodeSnippet}; if (result === null
by perfunctory 7y ago
This snippet doesn't look right
macro nullthrows(sourceCodeSnippet) {
return code`
const result = ${sourceCodeSnippet};
if (result === null || result === undefined) {
return result
} else {
throw new Error("Uh oh, this returned null:" + "${sourceCodeSnippet}");
`;
}
The first and the second occurrences of ${sourceCodeSnippet} look the same so I suppose it will just be evaluated twice. You don't want to evaluate the second occurrence, right? The lisp version doesn't have this problem.
- S4M 7y agoI think it's fine. In the first occurrence, $(sourceCodeSnippet) is replaced in the code, and later evaluated (and the result of this evaluation will be passed to the const result). In the second occurrence, it is replaced inside a string, so it doesn't get evaluated, but the source code is just treated as a string (and displayed in the error message). Note that the macro nullthrows is just generating some code depending of sourceCodeSnippet, and this code will be evaluated later.
- perfunctory 7y agoSince this is a pseudo code it's hard to tell what the intended semantics are, but if as you say "the source code is just treated as a string", then it's still not right. What if sourceCodeSnippet contains double quotes? OP conveniently uses single quotes in their example getUser(db, ‘billy’) The whole point of lisp macros is that code is not treated as a string.
- stopachka 7y agoHi perfunctory, thanks for the thoughtful read : ). I'll update that snippet to include something like a `stringify` function, to make the intent more clear. In terms of the intended semantics: - In some ways my intent was to show these limitations: unless we get code as data structures, our macros would be very brittle.
- perfunctory 7y agoIn this snippet parentheses are in the wrong place (defmacro nil-throws [form] `(let [result# ~form] ;; assign the evaluation of form to result# (if (nil? result#) (throw (ex-info "uh oh, we got nil!" {:form '~form}) ;; save form for inspection result#)))) I guess, should be (defmacro nil-throws [form] `(let [result# ~form] ;; assign the evaluation of form to result# (if (nil? result#) (throw (ex-info "uh oh, we got nil!" {:form '~form})) ;; save form for inspection result#)))
- stopachka 7y agoGreat catch! Updated, thank you :)
- awayfromhomenow 7y agolooks to me like the if/else construct is backward - it's going to return the the result if the sourceCodeSnippet evaluates to null or undefined, and throw an error if it doesn't... which iiuc is backwards from the intentt.