Closed olus2000 closed 2 years ago
Hi.
Thank you for the feedback. File handling is the most under-developed part of Quackery, mostly because it is not one of my programming strengths, so I am delighted that someone has picked up on it. For the time being at least, I'll be going with Solution 1, although long term I do like Solution 3. For various reasons I am taking an extended break from Quackery at the moment - mostly to clear my head and be able to return to it afresh. (I have M.E. It's a thing I have to do.)
I see that you committed "path support for file operations" to your fork a few minutes ago. Glad you are "going for it". Interested to see that you are going for a Python level solution. My initial reaction was to add a Quackery level extension redefining the file handling words to know about the file.path
ancillary stack, but I haven't thought it through at all.
Also kudos for the correction to matchitem
- I thought I had found all the times I omitted a nested
, but now I know that I missed at least one. :-) And your finding that particular one leads me to feel that I have at least succeeded in the goal of it being "possible to understand the entirety of Quackery in short order".
Gordon.
Thanks for responding so fast!
I've been charmed by Quackery ever since I saw it (which is for about a week 😃) and when I found a way to improve it I jumped at the opportunity. I also started by thinking of Quackery wrappers for the file handing functions as a proof of concept and I think they would not be hard to implement, so a path handling extension may be the 4th solution. The slight inconvenience there is that filename checking for loadfile
has to be duplicated in the wrapper and core loadfile
filename check would end up being unused.
I went for a Python solution because I wanted to make the change in the Quackery core and it turns out that base file handling words are in Python. That was actually convenient for me because I have loads more experience writing Python than Quackery. It wasn't too hard to find my way in the code and I hope my contributions don't change that.
As for the lacking nested
: I found it when trying to write a very bad lookup table word. Had I designed it better I wouldn't have to use such a convoluted predicate and wouldn't stumble into the problem. It wasn't easy to track down though: the only easily accessible symptom I had were zeroes being left on the stack and I had to use a lot of echostacks
s and echoreturn
s along with the source code provided in The Book of Quackery to find out where the problem was. Although I guess "an afternoon" is not that long for tracking down a bug in a language's source code.
Don't feel rushed to act on my issue, I'm happy to have received any feedback. You already did an amazing job making the language. My code will be there whenever you find time and will to check it out.
Alex.
Ha! This is the value of beta testing - we all stumble differently, and it is hard to stumble intentionally in a way that you would not stumble naturally.
Two tips I learned from my experience with the Forth community.
All of Quackery was rewritten many times before it went on GitHub.
Most of my difficulties happened when I was overconfident and ignored this advice because it was "so simple I could not possibly get it wrong!" (Especially before I had enough of Quackery working to code shell
- debugging was such a nightmare!)
I can understand preferring the language you are familiar with. When I started I did not know Python at all, other than I could see it would provide a path of least resistance. By the time I was half-way through developing Quackery I had done so many internet searches to figure out how to do something in Python that Google invited me to take their Google programmer test!
I still only know the parts of Python that were required to code Quackery. I wonder sometimes if I failed to find the best way to do some things, and have made hard work out of a piece of code that could be better, simpler, faster if I had learned more Python.
(Part of the problem for me was that many of Python's capabilities are hidden in the syntax of the language, and it is hard to find, for example, the syntax for slice notation, if you do not know that it is called slice notation, or that you should use the name of the function without the parentheses to reference a function, and append parentheses to a variable to make it perform the function it references. This is one of the things I like most about concatenative languages - there is hardly any syntax - every piece of functionality has a name.)
Don't worry about me rushing. I value thinking time far more than coding time. :-)
Hi,
I'm back after my Christmas break.
Before I get to making the updates on The Book of Quackery, I thought I would warm up by coding a solution to the file path issue.
Would you be able to take a look at my solution and tell me if you see any problems. I would appreciate a second pair of eyes to see it. I have the uneasy feeling that it was too easy and I might have missed something, but I cannot think what I forgot.
The updated version is here: https://www.dropbox.com/s/azc68kaw7wgnacm/quackery.py
Notes: I have done this without looking at your solution, as I wanted to see how much I remembered about coding in Python after a long break. The added code sections are each marked with the comment ***** .
(edit - I have also incorporated your corrections to backup
and bailed
.)
(2nd edit: Also I have simplified protected release protected put
to protected replace
in bailed
.)
Great work! Your code for filepath
is way cleaner than mine. Here are some issues and questions I have.
From least important:
is wrap$
and is words
on lines 1560 and 1564 respectively are misaligned with other is <word>
parts of other definitions.os.path.join
. In most cases the result will be identical, but os.path.join
is smart and does some additional processing. For example joining 'aaa'
with 'bbb'
produces a path 'aaa/bbb'
(with the slash or a backslash depending on the system), and joining 'aaa/'
with '/bbb'
produces an absolute path '/bbb'
.filepath
stack requires any program that would like to change the path relatively to the current working directory has to check if the filepath
stack is empty. If there was some default value on the stack at all times (for example .
) such programs could just filepath share
and join
the relative path they need.None of those are serious in any way and I haven't found any bugs when going through the diff. I didn't do extensive testing but it didn't break my previous programs and extensions, except from issue 3. which forced a quick fix for my extension loader.
Thank you. Corrections made. Your message was timely, I am close to pushing the revisions to GitHub - today I finished doing hypertext links in TBoQ, in the contents pages and the numbered notes in the code sections. (I expect to upload tomorrow, I will have a good opportunity to do some final checks in the evening.)
Valid points, but I have tried to minimise the number of Python libraries used, and os.path
is not strictly necessary. Python is "smart", Quackery assumes the programmer is smart. :-)
I imagine that Windows might require a different default path (I don't have a Windows machine to check, but I know it uses backslash instead of slash) and I would rather not introduce more system dependant code that I can't test. I note that the user could set a default path by putting $ "/" filepath put
or similar in extensions.qky
Edit: (Also, with or without a default value, putfile
, releasefile
, and sharefile
have to address the possibility that filepath
is an empty list, either by making it an error condition or treating it as a meaningful state.)
When loading a file from a subfolder
loadfile
gets not just the file's name but the whole path to it (accepts either relative or absolute, just as python does). This makes the circular dependency prevention useless in the form it has right now.loadfile
only checks the string it is passed versus any defined words, and the file's author can't be expected to guess from where their file will be loaded.Another problem occurs when a couple of files that depend on each other are stored in a subfolder as a package. They are unable to reference each other because relative paths are interpreted as relative to the Quackery instance.
I see three possible solutions:
1. Do nothing
Quackery is "a lightweight, open-source language for recreational and educational programming", so it may be out of the scope of its development to handle this issue.
2. Describe loading from subfolders as a bad practice
Actively discouraging working with subfolders is not unthinkable given that Quackery isn't meant to be an enterprise language, but it generates an ugly work space full of unorganised projects. I personally would prefer to work in subfolders even if it means manually resolving any circular dependencies and devising a programatic way of handling relative paths.
3. Add functionality to Quackery
My proposition is to add an ancillary stack
file.path
with a default path of"./"
on the top. Every file handling word will use the file name along with this stack's top item to construct the path of the file that should be affected. Whenever a file would be loaded that would require a different default path this path would just beput
on the stack for the time of loading andreleased
after that. New paths can be created in relation to the old ones byjoin
ing strings. It wouldn't break portability with any python-based Quackery system because python recognises/
as a path separator universally, and in other implementations it could be easily implemented too or left as en environmental dependency based on the underlying OS.