hylang / hy

A dialect of Lisp that's embedded in Python
http://hylang.org
Other
5.14k stars 372 forks source link

Would it be possible for (setv) to return its value? #2505

Closed Dima-369 closed 1 year ago

Dima-369 commented 1 year ago

I suppose it wasn't done since it is difficult to implement to map to the underlying Python code?

The usual Lisps I know of return the first variable value like this here in Emacs Lisp:

(setq test1 1 test2 3)
;; => 1

While in Hy, the value is not returned. I usually evaluate my code step sexp by sexp and it would be amazing if the value would be returned since one could see it instantly in the REPL.

Otherwise, one always has to evaluate the variable afterwards to see it. Anyway, just a minor thing in the end ;)

CleanShot 2023-09-04 at 15 15 52

Dima-369 commented 1 year ago

I suppose the same can be requested for forms like (defn) as well since evaluating it in the REPL returns nothing while Emacs Lisp returns the function name.

Kodiologist commented 1 year ago

Would it be possible for (setv) to return its value? I suppose it wasn't done since it is difficult to implement to map to the underlying Python code?

Exactly. Previous versions of Hy attempted to do this, and ran into trouble with usage like

(setv (get x (f)) (g))

What would this compile to? You don't want to call f or g more than once, and you need (get x (f)) to compile to something that Python will allow as an lvalue.

But you can always use setx instead, for the cases in which it's applicable.

I suppose the same can be requested for forms like (defn)

I think this would be possible, because defn, unlike setv, can only assign to a plain old symbol. I don't really see the application, though. Generally, when you want to return a function object, you use fn instead of defn.

Kodiologist commented 1 year ago

it would be amazing if the value would be returned since one could see it instantly in the REPL.

For what it's worth, this is regarded as a feature in Python. If you assign a massive object to a variable, you don't always want a massive representation printed to the console afterwards.

Dima-369 commented 1 year ago

But you can always use setx instead, for the cases in which it's applicable.

Oh, that's a good tip, thanks!

If you assign a massive object to a variable, you don't always want a massive representation printed to the console afterwards.

Very true! The Lisps usually have some kind of printer logic to accommodate such cases to fall back on an abbreviated string. For instance, there is print-level in Emacs Lisp.

I don't really see the application, though. Generally, when you want to return a function object, you use fn instead of defn.

Might just be me, but I got so used to the sexp evaluations in Emacs Lisp where evaluations pretty much always barfs something back. It's like a little confirmation every time ;)

CleanShot 2023-09-04 at 21 24 36


But I totally understand the reasoning here, thanks :)

So feel free to close.

Dima-369 commented 1 year ago

I still have one question about this topic.

Is there a reason why the REPL always spits out the entered input? It's a bit annoying to work with in *Hy* shell redirections.

Is there a way to disable it?

Kodiologist commented 1 year ago

I'm not sure I understand what you mean by "spits out the entered input". Hy uses Readline, which echoes each keystroke, and echo is generally what one expects for any terminal text entry other than a password. If you're seeing your input printed an additional time, that's not supposed to happen.

Please copy and paste your examples rather than taking screenshots.

Dima-369 commented 1 year ago

If you're seeing your input printed an additional time, that's not supposed to happen.

Oh, I always thought that's how it is. I tested in fish and there the input is correctly not printed an additional time. In eshell, I see it duplicated though as in the screenshot.

It's a bit annoying to work with in Hy shell redirections.

Sorry, it works. I just tested the following in Emacs Lisp. Not sure in what scenarios I saw it failing since it works now. So closing.

(defun dima-comint-execute-silently (process command)
  "Send COMMAND to PROCESS and return OUTPUT."
  (let ((output-buffer " *Comint Redirect Work Buffer*")
        ;; hide this being spammed into the message:
        ;; Blocking call to accept-process-output with quit inhibited!!
        (inhibit-message t)
        (message-log-max nil))
    (with-current-buffer (get-buffer-create output-buffer)
      (erase-buffer)
      (comint-redirect-send-command-to-process
       command output-buffer process nil t)
      (set-buffer (process-buffer process))
      (while (and (null comint-redirect-completed)
                  (accept-process-output process)))
      (set-buffer output-buffer)
      (goto-char (point-min))
      (and (looking-at command)
           (forward-line))
      (buffer-substring-no-properties (point) (- (point-max) 1)))))

(assert
 (string=
  (with-current-buffer hy-shell--buffer-name
    (dima-comint-execute-silently
     (get-buffer-process (current-buffer))
     "(setv a 1)"))
  "
"))