• 1 Post
  • 24 Comments
Joined 1 year ago
cake
Cake day: October 8th, 2023

help-circle

  • arthurno1@alien.topBtoLisp@communick.newsLispE
    link
    fedilink
    English
    arrow-up
    1
    ·
    10 months ago

    a gap buffer is a linked list in disguise

    I see a gap buffer more like a generalized std vector in regard to where you insert the items. I am not sure I understand why you think of it as a list, but perhaps we think about different things?

    And what you propose is basically what I have implemented.

    Mnjah; I am not sure we think of the same thing in that case. What I proposed, or what I asked why you didn’t do it that way, is to keep the “classical” Lisp semantics for lists so that you don’t need to rework many of the existing algorithms based on lists. No idea if that is important or not, but I don’t see a reason why you need to reverse those just because you use std::vector under the hood to store your lists. Where and how you push/pop could be kept just as an implementation detail.

    Another thing that I was thinking of is the cost of traversing the list. By generating a new object for each cdr operation and updating reference counters, it becomes quite costly compared to just returning a pointer. Have you done any benchmarks to compare your idea with the “classical” one? Also, have you looked into cdr coding; which is another technique to make list elements contiguous in memory?

    To note, perhaps a new Lisp could dispose with car/cdr operations, as long as you have some other alternative to access and traverse lists. After all cons/car/cdr/push/pop as we know them from classical lisp are defined as they are because of the implementation behind them. There is no definition of what a Lisp is, so nobody says a Lisp has to have those operations exactly as they are known in some older Lisps.


  • arthurno1@alien.topBtoLisp@communick.newsLispE
    link
    fedilink
    English
    arrow-up
    1
    ·
    10 months ago

    Interesting.

    The only case, when this structure is less efficient is when you need to insert an element at the head. In this case, we need to move all elements one step forward, which in a buffer is quite simple and efficient:

    Have you considered using a gap-buffer instead of ordinary vector?

    This solution certainly poses some problems and some traditional Lisp algorithms won’t work as expected.

    Since you are using C++, isn’t it possible to implement your own vector with overloaded operators to adhere to Lisp list semantics? In other words, isn’t it possible to make your car/cdr & other access functions access elements from the top of the stack so that ordinary list semantics as in standard Lisps still work as expected? Just a curious question, I guess you have already tried.


  • You don’t need to move files around just to bulk rename them. If you want to do it, sure, you can, but you don’t have to.

    In your top level directory:

    1. C-u C-x d (alternatively C-u M-x dired)

    You will be in minibuffer now. Be sure dired listing switches have -l and -R option; -l is probably already there among anything else you might use; just type space and add -R at the end and type Return (Enter)

    Now you will have a Dired buffer with al the subdirectories and files in them listed in the same buffer.

    1. C-x C-q in Dired to switch to WDired mode (I have bound it in my Emacs to C-S-r for easier typing)

    You are now in “writeable dired” mode where you can edit all file names as if it were an ordinary text buffer. You can also use replace-string for example to replace a part of the name in all filenames at once, regex-replace, etc. You can do it manually, or whatever else you would do in a text buffer.

    1. C-c C-c to save your changes when you are done; all files will be updated.




  • I can tell that I’ve noticed some improvements.

    I guess you haven’t run your Emacs for a long time, because ~100 megabytes of allocated memory will take its time to GC check. With that amount of RAM, you will probably notice Emacs “stuttering”, like freezing for small periods of time when using it normally. The bigger the gc-cons-threshold value, the longer time it will take for GC to check the memory. Emacs does not have an incremental and multithreaded GC, so your Emacs will appear as frozen to you.

    (defun salih/maybe-gc ()
      (let ((original gc-cons-threshold))
        (setq gc-cons-threshold 800000)
        (setq gc-cons-threshold original
              gc-timer (run-with-timer 2 nil #'salih/schedule-maybe-gc))))
    

    Have you even looked at gc-cons-threshold value; after your idle timer has finished the work? Looking at your code, I believe you will be surprised because it does not seem to be what you think it will be.

    What is the point of the first setq there?

    In the third line, you are setting the value to hardcoded ~800 kb (I think it is the on 64-bit systems, but it is not so important), just to immediately override it with 100 meg as you defined it in the previous code piece (third line of your code), one after the gcmh. Secondly, what is the reason to use gcmh package if you are going to do it all manually :). GCMH will do exactly the same thing you are doing manually in that example if I am not mistaken; I don’t use that package myself, but someone wrote it for the purpose of automating that little hack you are trying to make there. IMO, either use that package and be happy, or do it all manually.

    What is the purpose of setq-ing gc-timer to run your function in that let-body (last line) which appears to just do exactly the same - you are again doing the same thing in your salih/schedule-maybe-gc. You are just telling Emacs in an infinite loop to set up a new timer when it is idle. If you believe you are telling Emacs to actually garbage collect something, you are wrong; you are just setting up another timer.

    In other words; your code does not do what you believe it does; it is rather plain wrong, in other words, buggy, to put it mildly.

    I can tell that I’ve noticed some improvements.

    I can tell you haven’t, you just don’t know about it. When other posters here told you to benchmark they were correct.

    we are not in an academic seminar, such anecdotal statements should be authentic enough.

    We don’t benchmark because of being academics, but because of ourselves. If we won’t to improve something in whatever terms, cpu execution time, memory usage, number of resources allocated (timers, files, sockets etc.) you have to measure. You can’t know for sure if you don’t measure, there is no way. Your computer can be doing stuff, your application can be doing stuff, and so on. Modern computer systems are not deterministic in terms that hardware usage being exactly the same each time you run an application. Execution time is highly dependent on your OS and CPU scheduler(s), memory usage patterns and so on, some of the things your application usually does not influence explicitly.

    Without measuring you are walking with a blindfold. However, you seem to have other problems than just benchmarking your stuff; you should really read the manual about stuff you are trying to improve or change, use built-in help; C-h f/v to see what stuff does and try to understand it. Read whichever blog posts you have found again and reflect carefully on what they say and why. Just blindly copying stuff without understanding it results in stuff like your code above.

    Finally, to answer your original question, it all depends on how you wish to use your Emacs. What might be fast for one usage pattern, might not be fast for another one. Again, you will have to know what you are doing and to measure for your particular use-case.


  • the prefix seems to be a common Common Lisp library prefix.

    Yes it is, but is that important?

    I would think of what is the target audience. If it is a general home automation crowd, for them the programming language used is just an implementation detail, not the major reason to choose the project.

    Of course, the name is not the most important thing either, it was just my reflection since the discussion was about it.


  • when I use dired to follow a Windows shortcut it still opens it as a file

    Have you enabled parsing of lnk files; as they say in the docs, you have:

     (customize-option 'w32-symlinks-handle-shortcuts)
    

    You can just

    (setopt w32-symlinks-handle-shortcuts t)
    

    However, when I tried it, they don’t seem to parse correctly the name; the last part of the name is surrounded by ‘#’ characters for some reason, so Emacs reports no such file found. I haven’t looked in depth at how they parse stuff and where.


  • I agree that cl- prefix or -cl suffix is probably not the best idea for a project name, there are already loads of those seems like, I would agree with you that a personal name is not the best idea either. I would rather use something more descriptive that makes people understand what it is about when they see it in a web search or stumble upon it on Github.

    Cool project by the way; thanks for sharing.


  • What is value of your find-file-visit-truename? Somewhere in your init file:

    (setq find-file-visit-truename t)
    

    and see if it helps.

    I deleted my configuration, reinstalled emacs, and then followed the instructions again.

    It is not Windows 98 you are configuring there. No need to reinstall Emacs. If you have messed up badly just remove your init file and restart Emacs.


  • But I struggle to achieve my learning of Elisp.

    I think it is on your side. Sorry to tell it open, but Lisp(s) are very easy to learn and pick up. I don’t know what you are teaching and what your expertize is in, but for me Lisp was as easy as VisualBasic.

    The documentation is austere.

    Emacs and Emacs Lisp are by fart the most documented Lisp applications. I can agree that it might be a bit outdated in terminology, and both terminology and API need some acclimatization since they predate the terminology we use today, and Lisp is a bit different from your ordinary Python/C/Java-like language. But I wouldn’t say it is very hard; just different.

    I found TODAY by CHANCE in this page

    It has been in your Emacs all along, for a long time, since it is a part of Org manual that comes with your Emacs. You have to be more curious about what you are doing if you want to learn it and understand it. Nobody is going to throw knowledge at you; that happens only in classes. As a teacher, you should know that better than anyone else. If you want to learn and develop as Elisp programmer you will have to dig in yourself, be curious, search, read manual. Emacs Lisp is one of the most discoverable and documented Lisps and probably programming languages at all. You can C-h f to see docs directly in Emacs, and than just ‘s’ in help window to see the source code. There are manuals for many parts of Emacs, including Org, that are built into your Emacs; you have debugging tools and lots of code to look at. You can also use Helpful which shows you the source code per default.

    we don’t have a smooth learning experience with Emacs

    A learning experience is very subjective. It depends on many things. One of them is a person’s ability as well as the will to learn.

    Am I the only one to experience this ?

    Probably not the only one, but also probably not the most representative example either. I am sorry. I am not trying to put you down as a person, but just suggesting that you should be more active, curious and looking for help yourself. As said, people can only provide you with manuals and material, but you have to look it up yourself, unless you can find an Emacs course. There are some online, perhaps that suits you better? Might be worth your time and small money investment. Perhaps look at some videos, or simply search for Elisp tutorials. There are some around.




  • I don’t know. I found it yesterday by a chance; was looking for Invistra, but couldn’t remember the name; searched on “Common Lisp format library” and that one popped up too. Took like just few minutes to understand it and adapt it, so that is where I see the value.

    The biggest problem with it seems to be it does not support string escapes, like a new line; at least not for me; perhaps I don’t understand it yet; will look at that later.

    I also have no idea how it compares performance-wise with real printf via FFI; I am not sure if that really matters though.



  • CLISP is abandonware, even though the riches of the golden age when it was researched and worked on are still there

    I don’t know how much they consider it complete and how much they just don’t work on it, but there are some updates from time to time; I see the creator Bruno is pushing fixes from time to time.

    I tried GCL, but let’s not talk about that.

    :-) I would be interested to hear the experience. I am aware of it, but I haven’t had time to try it myself. They also seem to be on very sporadic development.

    I personally haven’t tried Clasp, CMUCL, CLisp and GCL yet; I just don’t have time. It takes time to try everything properly, build it etc, so I am currently just using sbcl; but I would be interested to know how other implementations compare in terms of completeness, extras they offer, performance, correctness etc. I would even watch a YT video if some YouTuber was interested in making a review wink wink you know who you are :).



  • I suppose that melpa downloads can be used as a measure of usage.

    Not necessarily; lots of people would test some stuff and than perhaps not use it, or after some time go over to something else and so on. I wouldn’t rely on download stats.

    which extensions are used often in users setup

    It would be certainly possible to monitor which files are required in your Emacs session, and you could setup a public server somewhere on the Internet where such stats are uploaded, putted together and published for viewing. But what would that matter to you what I or some other Joe are using? Learn a thing and build on it instead of switching and trying. As long as it solves your problems who cares what others are using?


  • What I tried is to feed to minibuffer word string.

    So you have called:

    M-: (type-of (read)) RET string RET?
    

    You have just created a temporary symbol named “string”. You can try this to see for yourself:

    M-: (symbol-name (type-of (read))) RET
    

    If you want a string object out of “string”, you will have to quote it in the minibuffer too:

    M-: (type-of (read)) RET "string" RET?
    

    I think you should have not downvoted /u/lispm below (or whomever it was); he has given a few very good questions to get you going on in exploring those things on your own.