You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(13) |
Sep
(7) |
Oct
|
Nov
(4) |
Dec
(2) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(1) |
Feb
(2) |
Mar
(1) |
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(9) |
Sep
(5) |
Oct
|
Nov
|
Dec
|
From: Cynbe ru T. <cy...@mu...> - 2002-09-21 19:44:04
|
Drake Wilson <dr...@li...> writes: > Would it be possible to make compiledFunctions not pure read-only but > write-once? Have the assembler write the function once, after which > it cannot be written again. Then again, that's probably added > complexity. Hmm. Write-once slots are an independently cool idea -- logic programming gets lots of milage from datastructures which cannot be modified in a normal sense, but have write-once slots from which they can be extended. Computations hitting a write-once slot can be suspended until that value becomes defined, in at least some approaches. (promises are sort of a variant of write-once, in that they evaluate at most once and then save the value in what is de facto a write-once slot.) I've mulled over some sort of write-once support for Muq, but it has never gotten to the top of the priority list. I'm not sure it would be a big win in this particular context. But I'm not sure it wouldn't. :) > > Still, in general we indirect calls through > > Symbols so as to be able to transparently > > recompile a function later without having to > > recompile every compiledFunction which calls > > it (and thus recursively outwards): Should not > > be too hard to do this right. > > *nods* Anonymous Symbols, pointing to the compiledFunctions? I think > I might be reading this incorrectly. subroutine-local variables in Muq are just stack slots, for space and time efficiency, but basically all global symbols like classes, named functions, global variables &tc are implemented as lisp-style Symbols. So when we compile a call to a named function, the code we typically actually compile is a bytecode CALL pointing to the relevant Symbol. When we recompile that function, we set the function slot in that Symbol to point to the new compiledFunction instance, resulting in all future calls via that symbol automatically invoking the new version of the function. The old compiledFunction will still exist until garbage-collected, however, and if calls to the old version are running, they will continue to use the old version until they exit. So the trick of indirecting calls through Symbol instances makes a lot of stuff work the way you'd like it to, at the cost of an extra indirection per call. The alternative of having compiledFunctions call each other directly and then somehow hunting down and patching all the references to a compiledFunction each time it is recompile, was too horrendous to even think about. :) > (chainsaw) > > Since you still haven't Given Up And Gone Away, :) > > I'll try to take a look at the closure issue this > > weekend. I hate it when defects in my code become > > the limiting factor on someone else doing > > something cool! > > Strictly speaking, they're not. :-) I tried to use Scheme for this. > However, the multiple conflicting implementations, odd issues with > compilation, libraries, not enough builtins, then I/O, not being able > to run the interpreter non-interactively in a simple manner, having to > filter out all the extra messages, etc. kind of put me off. So I > thought, MUF is Lisplike Forth, and very fast -- wonderful. It just > didn't do the necessary closures, that's all. I tried it in Perl, but > it was a bit too slow and the syntax didn't make it very easy to do. Interesting! I've been following Scheme out of the corner of my eye since the days of Guy L Steele's Rabbit compiler, but I've never tried to do anything practical in it. All the cool implementation techniques seem to get demonstrated on Scheme first. I actually tried using scheme as Muq's reference semantics for awhile, but there were just too many things Muq needs to do which Scheme hasn't standardized. Using commonlisp extensions to scheme would have been a horror, since they don't even agree on how to handle boolean values. So I switched to CommonLisp as a stable reference. Unfortunately, CommonLisp is looking a lot deader than I would like, and time has not been kind to the commonlisp OOP approach, which is looking more and more out of step with the general direction of thought and experience about good programming practices. Still, I don't see anything clearly better. C++ is a pragmatically useful horror of historical kludges. Java is trying too hard to be a low-level competitor to C/C++ to be a good model for a high-level application language. Languages like Perl and Python come and go like Paris fashions, so they aren't much use for a system designed to support persistent databases for decades -- and in fact both the Perl and Python people have announced that they've decided the current versions of the language are too broken to support in future releases. Ada? *cough* Or spin the dial and pick randomly from the welter of me-too languages with no significant following. > Hmm. C, with function pointers, maybe. You can do anything in C except munge the stack portably. But you wind up doing a painfully large amount of stuff by hand if you've got nontrivial goals. Muq is circa 100,000 lines of C implementing the stuff one would like for a persistent virtual-world system: One probably can't do equivalent functionality in a whole lot less. What one might be able to do would be to put together enough pre-existing libraries to provide most of what you want, starting say with the Texas Persistent Store. Then you just have the joy of making them work together. :) I'm currently playing with pure-functional stuff in a next-generation muq prototype called 'neu' for the moment. My chance to play with various neat ideas that didn't fit in the current Muq implementation. I did a little trial hack this week to test out the Linux dlopen()/.../dlclose() dynamic link support, which I've also never played with before. Running all mud source code through a translator to C, then through gcc, then dynamically linking it in, is one inviting alternative to a classic bytecode interpreter: A poor man's incremental compiler done on the cheap, with potentially very good performance in terms of the sort of tight inner loops where bytecode interpreters suck. You lose the code density of bytecode, but nobody really cares about that any more, and running stuff through gcc will be a bit slower than using an in-process bytecode compiler, but on today's machines, probably not enough that people will complain much. Timeslicing got harder, but Linux sounds like will finally have a decent POSIX threads library within a year or two -- one might at long last be able to leave timeslicing worries to the kernel by simply making every virtual world job a separate host thread. I looked a bit at using C++ instead of C as the core implementation language for somethign like Muq, but that looks like a bloody pain -- gcc apparently doesn't support the convention of assigning to 'this' in a constructor, and in general dealing with the hidden vtable pointer stuff in a persistent heap looks like a mess. You're going somewhere the C++ implementors didn't expect or intend you to go, and C++ is one of those huge, complex, fragile monstrosities where if you stray off the beaten path, you're in for a world of pain. (Which imho doesn't leave a lot of things C++ should be used for. :) C++ is too crashprone and bugprone to be a sane choice for writing the bulk of stuff like Evolution -- that should be written in something like Python. And the core and efficiency-critical stuff is still better written in C than C++. So that leaves for C++ a few things like embedded programming where space/time efficiency is still more important than maintainability.) > As an aside, my other two Muq-using pieces have been suspended; the > world server is on hold due to (a) major design issues with > distributedness which may or may not be tractable in their current > form I'd be curious to hear about these, since I've done a fair amount of thinking about this, and Muq has a limited amount of support for this. (Limited compared to what one might really like; More I think than any comparable system.) > and (b) waiting for email permission to use the Inform Platypus > parser. qpkg is waiting for either myself or someone else to figure > out how the dbfiles and users fit together exactly and document it. > And everything else has taken a hit with the newly started academic > term. Funny how that works. And then when you graduate and Get A Job, it takes a fatal hit. At least, that's the typical pattern. > ----> Drake Wilson -- Cynbe |
From: Drake W. <dr...@li...> - 2002-09-21 03:57:15
|
On Fri, Sep 20, 2002 at 03:50:27PM -0500, Cynbe ru Taren wrote: (scissor) > So it should be possible to have the Assembler > remember which local variables are potentially > shared and which are not, and during the final > pass of actual bytecode generation, to generate > appropriate code accordingly. This might also > involve new bytecodes to read-indirect and > write-indirect through a pointer to a symbol, > but that's backward compatible if I/we do it > that way. >=20 > (Thoughts and suggestions are welcome, but I > doubt anyone but me has dug through the relevant > code enough to much know or care about design > decisions at this level.) True. > The other really galling thing on this front is > the current inability to have a function call > itself recursively in any natural fashion. > Mechanically, in the compiler, this is mainly > because the compiledFunction to be called doesn't > actually exist during compilation -- it is created > as a logically atomic operation at the end. So > the usual logic for generating a call to a > compiledFunction just doesn't work very naturally > in this case. We can't create the > compiledFunction ahead of time and then fill it in > later if we want compiledFunctions to be strictly > read-only. (The michief potential of > compiledFunctions which can be modified while they > are running is not something I even want to think > about...) (Note that I haven't dug through the relevant code/comments/etc. and so I may be far off base.) Would it be possible to make compiledFunctions not pure read-only but write-once? Have the assembler write the function once, after which it cannot be written again. Then again, that's probably added complexity. Hmm. > Still, in general we indirect calls through > Symbols so as to be able to transparently > recompile a function later without having to > recompile every compiledFunction which calls > it (and thus recursively outwards): Should not > be too hard to do this right. *nods* Anonymous Symbols, pointing to the compiledFunctions? I think I might be reading this incorrectly. (snip) > Which is what Fred Brooks in his indispensable The > Mythical Man-Month called "the tar pit": The cave > bear sinking slowly into the tarpit can easily > free any individual paw or other body part, > it is just the inability to free all of them > at once that kills him in the end. :) IBM could > easily have completed any given part of the new > national air traffic control software system, it > was only the task of completing all of it that > proved impractical. Oh yes... (chainsaw) > Since you still haven't Given Up And Gone Away, :) > I'll try to take a look at the closure issue this > weekend. I hate it when defects in my code become > the limiting factor on someone else doing > something cool! Strictly speaking, they're not. :-) I tried to use Scheme for this. However, the multiple conflicting implementations, odd issues with compilation, libraries, not enough builtins, then I/O, not being able to run the interpreter non-interactively in a simple manner, having to filter out all the extra messages, etc. kind of put me off. So I thought, MUF is Lisplike Forth, and very fast -- wonderful. It just didn't do the necessary closures, that's all. I tried it in Perl, but it was a bit too slow and the syntax didn't make it very easy to do. Hmm. C, with function pointers, maybe. As an aside, my other two Muq-using pieces have been suspended; the world server is on hold due to (a) major design issues with distributedness which may or may not be tractable in their current form and (b) waiting for email permission to use the Inform Platypus parser. qpkg is waiting for either myself or someone else to figure out how the dbfiles and users fit together exactly and document it. And everything else has taken a hit with the newly started academic term. > On the other hand, the Austin Texas weather just > cooled down enough for me to open the window for > the first time in months: Maybe I'll spend the > weekend pretending I have a life. :) Good idea. :-) > -- Cynbe ----> Drake Wilson |
From: Cynbe ru T. <cy...@mu...> - 2002-09-20 20:50:42
|
(My comments follow.) Drake Wilson <dr...@li...> writes: > Quoth I toward the root mufShell: > > : sine { $ $ -> $ } > -> freq -> amp > > :: { $ -> $ } > -> x > x freq call{ $ -> $ } > 2 pi * * * 44100 / sin x amp call{ $ -> $ } * > ; > ; > > But nay, Muq was not pleased: > > Sorry: Undefined identifier: freq > dsnd: > Sorry: Need fn or cfn! > dsnd: > Sorry: Undefined identifier: pi > dsnd: > Sorry: Undefined identifier: x > dsnd: > Sorry: Undefined identifier: amp > dsnd: > Sorry: Need fn or cfn! > dsnd: > Sorry: pull: stack is empty. > dsnd: > dsnd: > Sorry: pull: stack is empty. > > Hath Muq Forth not the ability to compile closures? Was much of it > not derived from Common Lisp, where closures abound; was not the > closure, whence is derived much of the goodness of the anonymous > function, thence borrowed? > > </quasi-archaic-English> > (My quasi-archaic-English is probably wrong; please forgive.) > > That said, I _am_ surprised that closures don't DWIM in MUF. Thunks > and promises won't really work here, because the new function will > need to be called many times with different parameters. Using global > variables or parameters on the job or some other object seem like a > really kludgy workaround. What gives? > > ----> Drake Wilson You're entirely right: For those who have learned to use them, closures do Cool Stuff which can't be cleanly done any other way. This is a lacuna. Proper closures were (and are) planned and valued. Doing Real Closures has been pretty high on my TODO file for some time. I held off partly because the typical folks Muq attracts aren't much on using closures :) and thus it was something that could be deferred a bit. Toward the end of the pre-beta period, my working rule became: Don't fix anything now which can just as well be fixed post-beta in backward-compatible fashion. That included anything purely in softcode, and this closure implementation issue is either largely or entirely in softcode, depending how it is attacked. (It is just unfortunate that finances and exhaustion between them resulted in little being done between first beta and now.) But the main reason I held off implementing true closures was because doing so involved a design decision I wasn't sure about: 1 It would be very nice if compiledFunction objects were pure (read-only) so as to be freely cached, copied &tc, particularly in the distributed-networking context. 2 It would be most space and time efficient to implement captured variables of the closure variety just like elements of the compiledFunctions built-in constant vector, except writable. Access to the interior of the compiledFunction can be very space and time efficient -- say, roughly, 10X cheaper. This observation, however, conflicts directly with (1). 3 Under the right circumstances, the variables captured by a closure can remain visible to other closures or functions, If they are implemented as in (2), this becomes sticky -- compiledFunctions twiddling the contents of other compiledFunctions looks particularly messy. One could use two implementations of captured variables, a fast+compact one ala (2) for the unshared case, and a slower one using an external object to hold the shared state in the case where the compiler can't prove that access will be unshared. But complexity tends to feed on itself, and it isn't at all clear that the complexity of dual implementations can be justified in this case. At this point, I've pretty much settled on the virtues of simplicity and of pure compiledFunctions as being the most important: I think capture of environmental values by closures should always be done by creating a Symbol instance to hold the captured value, and then storing pointers to that shared Symbol in the constant vectors of the compiledFunctions in which that variable is visible. Unfortunately, that still means that we have dual implementations to the extent that if a local variable in one function is found to be visible in a closure it creates, that we need to implement that local variable as a full-fledged garbage- collectable Symbol on the heap rather than as a fast, simple slot on the return/control stack: Looks like everywhere that the compiler generates an access to that variable, the code generated will depend upon whether it is shared or not. Unfortunately, Forth traditionally uses a word-at-a-time assembler-style compilation mode, and the Muq MUF compiler follows this tradition, so it will in general already have generated code references to a variable before it even sees the closure which makes it shared. Muq does however use an Assembler class which buffers up all the code for a function before doing final code generation. Partly to optimize the bytecodes a bit -- use 8-bit jump offsets rather than 16-bit where possible -- and mostly to provide a 'security kernel' encapsulation of the code generation process so that user-written compilers can be guaranteed not to produce compiledFunctions which will crash the virtual machine, no matter how maliciously written. So it should be possible to have the Assembler remember which local variables are potentially shared and which are not, and during the final pass of actual bytecode generation, to generate appropriate code accordingly. This might also involve new bytecodes to read-indirect and write-indirect through a pointer to a symbol, but that's backward compatible if I/we do it that way. (Thoughts and suggestions are welcome, but I doubt anyone but me has dug through the relevant code enough to much know or care about design decisions at this level.) The other really galling thing on this front is the current inability to have a function call itself recursively in any natural fashion. Mechanically, in the compiler, this is mainly because the compiledFunction to be called doesn't actually exist during compilation -- it is created as a logically atomic operation at the end. So the usual logic for generating a call to a compiledFunction just doesn't work very naturally in this case. We can't create the compiledFunction ahead of time and then fill it in later if we want compiledFunctions to be strictly read-only. (The michief potential of compiledFunctions which can be modified while they are running is not something I even want to think about...) Still, in general we indirect calls through Symbols so as to be able to transparently recompile a function later without having to recompile every compiledFunction which calls it (and thus recursively outwards): Should not be too hard to do this right. Anyhow, that's why closures are (or aren't) what they are in Muq at the moment. In general, a system like Muq is never really finished: Instead it just has various open fronts on which different amounts of progress have been made. As one uses them, one eventually reaches the front and asks the obvious question: Why hasn't it been pushed back another 100 yards already? It would be so easy to do! Which is exactly right, in every specific case. What is difficult is only the totality of all the easy things which need doing. Which is what Fred Brooks in his indispensable The Mythical Man-Month called "the tar pit": The cave bear sinking slowly into the tarpit can easily free any individual paw or other body part, it is just the inability to free all of them at once that kills him in the end. :) IBM could easily have completed any given part of the new national air traffic control software system, it was only the task of completing all of it that proved impractical. I've actually been thinking a bit about Muq compilers of late. I still like the idea of an at least vaguely python-ish language for Muq. The soul of Strunk and White's "Elements of Style" is the simple maxim that "briefer is better" -- I'd kind of figured that at some point programmers would tire of that excess of syntactic sugar which "leads to cancer of the semicolon," and be open to something a bit less cluttered: I take the relatively broad acceptance of Python as evidence of that moment having arrived. So I spent some time this week poking through Guido's lexing code to see how he handles significant-indentation, since I've never done that before. Turns out he just has the lexer keep a stack of all the currently active indentation levels, and then generate virtual opening and closing braces accordingly. More or less what I'd figured, except for the stack -- I'd figured he would assume a fixed indentation scheme and dispense with the stack. (The code also has lots of the various sorts of little tweaks which only come from practical experience with the code, such as respecting the vi-specific tab settings which can be hidden in comments.) Since his code is the end result of lots of practical experience, it would be nice to do things his way on this front. Presuming I can find a way to shoehorn a lexer stack into Muq in backward-compatible fashion. :) Since you still haven't Given Up And Gone Away, :) I'll try to take a look at the closure issue this weekend. I hate it when defects in my code become the limiting factor on someone else doing something cool! On the other hand, the Austin Texas weather just cooled down enough for me to open the window for the first time in months: Maybe I'll spend the weekend pretending I have a life. :) -- Cynbe |
From: Drake W. <dr...@li...> - 2002-09-19 02:54:39
|
Quoth I toward the root mufShell: : sine { $ $ -> $ } -> freq -> amp :: { $ -> $ } -> x x freq call{ $ -> $ } 2 pi * * * 44100 / sin x amp call{ $ -> $ } * ; ; But nay, Muq was not pleased: Sorry: Undefined identifier: freq dsnd:=20 Sorry: Need fn or cfn! dsnd:=20 Sorry: Undefined identifier: pi dsnd:=20 Sorry: Undefined identifier: x dsnd:=20 Sorry: Undefined identifier: amp dsnd:=20 Sorry: Need fn or cfn! dsnd:=20 Sorry: pull: stack is empty. dsnd:=20 dsnd:=20 Sorry: pull: stack is empty. Hath Muq Forth not the ability to compile closures? Was much of it not derived from Common Lisp, where closures abound; was not the closure, whence is derived much of the goodness of the anonymous function, thence borrowed? </quasi-archaic-English> (My quasi-archaic-English is probably wrong; please forgive.) That said, I _am_ surprised that closures don't DWIM in MUF. Thunks and promises won't really work here, because the new function will need to be called many times with different parameters. Using global variables or parameters on the job or some other object seem like a really kludgy workaround. What gives? ----> Drake Wilson |
From: Cynbe ru T. <cy...@mu...> - 2002-09-03 18:18:46
|
Hrm, at the moment, at least, http://premchai21.perlmonk.org/muq/ isn't coming up for me. I'll try again later... Drake Wilson <dr...@li...> writes: > *whew* > > I have written a muq-forth-mode for Emacs (currently only tested under > XEmacs). It can be found in the directory > <http://premchai21.perlmonk.org/muq/>. The README file is copied > here (delimited by "+~~~~+"): > > +~~~~+ > muq-forth-mode is a mode for editing Muq Forth code in Emacs. > It has only currently been tested under XEmacs 21.4.8. > > Features: > > * fontifies comments, strings, most definitions, arities, variable > assignments, symbols, keywords, and most common control constructs. > * indents most common control constructs. > > Known issues: > > * indenting certain kinds of lines leaves point in weird places > * probably not nearly as efficient or well-commented as it should be > (especially in muq-forth-indent-levels) > * syntax table is a bit wonky in places (AFAICT it is not possible to get > Emacs to handle [ ... | or : ... ; properly without breaking something > else or writing huge amounts of nearly-duplicative code) > > muq-forth-mode is released under the terms of the GNU General Public > License. > > That is all. Should you still desire to, go forth and use it (pun not > intended). > +~~~~+ > > Share and enjoy, > > -----> Drake Wilson |
From: Drake W. <dr...@li...> - 2002-08-31 03:58:09
|
*whew* I have written a muq-forth-mode for Emacs (currently only tested under XEmacs). It can be found in the directory <http://premchai21.perlmonk.org/muq/>. The README file is copied here (delimited by "+~~~~+"): +~~~~+ muq-forth-mode is a mode for editing Muq Forth code in Emacs. It has only currently been tested under XEmacs 21.4.8. Features: * fontifies comments, strings, most definitions, arities, variable assignments, symbols, keywords, and most common control constructs. * indents most common control constructs. Known issues: * indenting certain kinds of lines leaves point in weird places * probably not nearly as efficient or well-commented as it should be (especially in muq-forth-indent-levels) * syntax table is a bit wonky in places (AFAICT it is not possible to get Emacs to handle [ ... | or : ... ; properly without breaking something else or writing huge amounts of nearly-duplicative code) muq-forth-mode is released under the terms of the GNU General Public License. That is all. Should you still desire to, go forth and use it (pun not intended). +~~~~+ Share and enjoy, -----> Drake Wilson |
From: Cynbe ru T. <cy...@mu...> - 2002-08-26 16:46:28
|
Drake Wilson <dr...@li...> writes: > Is there any way to know from within a function which function called > it? > > More specifically, I would like to have a class with a slot accessible > only by the class, but would like to write a function (not, > syntactically speaking, a class function) which acts as a constructor > with arguments; however, it will need to access the slot in question. > Writing a function to access the slot is possible, but I wish that > function to throw an error if it is called by anything other than the > constructor. How is this possible, if at all? > > ----> Drake Wilson There's nothing specifically designed to support that right now. The only existing functionality I can think of that would be useful for this is the loop stack inspection facility: See "loop stack functions" in the muf manual. It is primarily intended for debuggers and such, but you should be able to fish the calling function out of the next regular stackfrme up the loop stack. That should be fast enough for a constructor that isn't used too heavily. (If this becomes a bottleneck, we might need to craft a more suitable server primitive to support this.) Muq stores a variety of different types of information on the loop stack -- any nested context which may need virtual machine attention during an unwind/throw -- so you'll need to be prepared to step through irrelevancies like that until you get to the next generic call frame on the stack. I forget why I settled on "loop stack" rather than "call stack" terminology. Same thing. Maybe I was emphasizing that lots more things than just return addresses live on it. For more information on the full range of loop stack frames supported in Muq, see the "Loop Stacks" section of the muq implementation manual. Quoting from it: Muq supports the following kinds of loop stack stackframes (so far): JOB_STACKFRAME_THUNK , pushed when starting evaluation of a thunk. JOB_STACKFRAME_NORMAL , pushed by a normal CALL or EXECUTE; JOB_STACKFRAME_CATCH , pushed by a CATCH@{ @} command. JOB_STACKFRAME_TAG , pushed by a TAG@{ @} command. JOB_STACKFRAME_TAGTOP , pushed by a TAG@{ @} command. JOB_STACKFRAME_LOCK , pushed while running with-lock-do@{ ... code. JOB_STACKFRAME_LOCK_CHILD, pushed while running with-child-lock-do@{ ... code. JOB_STACKFRAME_NULL , unwanted LOCK frames get changed to this. JOB_STACKFRAME_USER , pushed while running as-me@{...@}/as-user@{...@} code. JOB_STACKFRAME_PRIVS , pushed while running omnipotently-do@{...@} code. JOB_STACKFRAME_PROTECT, pushed while running after@{ ... clause code. JOB_STACKFRAME_PROTECT_CHILD, pushed while running after-child-does@{ ... JOB_STACKFRAME_THROW , pushed while running @}always_do@{ ... code in throw. JOB_STACKFRAME_ENDJOB , pushed while running @}always_do@{ ... code in endjob. JOB_STACKFRAME_EXEC , pushed while running @}always_do@{ ... code in exec. JOB_STACKFRAME_GOTO , pushed while running @}always_do@{ ... code in goto. JOB_STACKFRAME_RETURN , pushed while running @}always_do@{ ... code in return. JOB_STACKFRAME_JUMP , pushed while running @}always_do@{ ... code in jump. JOB_STACKFRAME_VANILLA, pushed while running @}always_do@{ ... code normally. JOB_STACKFRAME_RESTART, pushed by a ]with-restart-do@{...@} command. JOB_STACKFRAME_TMP_USER,pushed while running handlers. JOB_STACKFRAME_FUN_BIND,pushed when binding a function to a symbol. JOB_STACKFRAME_VAR_BIND,pushed when binding a value to a symbol. JOB_STACKFRAME_EPHEMERAL_LIST, pushed when storing one on stack. JOB_STACKFRAME_EPHEMERAL_STRUCT, pushed when storing one on stack. JOB_STACKFRAME_EPHEMERAL_VECTOR, pushed when storing one on stack. Quite a raft of machinery, but important to implementing the virtual machine's guarantee that locks held by a job -always- get released when it is killed and similar good things. Fortunately, app hackers can ignore all that stuff under the hood 99% of the time. Just as a practical engineering note, these days I'd be inclined to get the cool end-user functionality working first, and sweat these sorts of security details later (as long as they don't impact the fundamental design). Muq is sort of living proof that effective userbase recruitment is more critical than technical soundness in practice. :) Alas... -- Cynbe |
From: Drake W. <dr...@li...> - 2002-08-25 22:28:35
|
Is there any way to know from within a function which function called it? More specifically, I would like to have a class with a slot accessible only by the class, but would like to write a function (not, syntactically speaking, a class function) which acts as a constructor with arguments; however, it will need to access the slot in question. Writing a function to access the slot is possible, but I wish that function to throw an error if it is called by anything other than the constructor. How is this possible, if at all? ----> Drake Wilson |
From: Drake W. <dr...@li...> - 2002-08-18 06:28:24
|
On Sun, Aug 18, 2002 at 12:35:34AM -0500, Cynbe ru Taren wrote: >=20 > Drake Wilson <dr...@li...> writes: >=20 > > This message is thus being cc'ed to muq-bugs, as the exitShell > > malfunction and the seemingly-useless rootAsUserDo{ } could probably > > be considered bugs. >=20 > I'll deal with that part separately. (claw) *blink* Deal with which part separately from what? > > PGP is what I was thinking, yes, though putting it directly in is > > probably faster (and otherwise better?). (splice) > Also, the Muq virtual machine currently won't timeslice during > the a-to-the-b-mod-c operation, (warp) > but using PGP externally (so we benefit from > host timeslicing) is an easier, quicker fit to keep interactive > performanace snappy in Muq. >=20 > On the other hand, the less we use external programs, the more > portable we are. There's also the overhead of starting another PGP/GPG process, and its initialization overhead, and what happens when it tries to read from the tty... > > > The MIME standard(s) are another motherload we can mine for this > > > sort of stuff: They have both protocols and code for signing > > > arbitrary content. We might be able to leverage all that to > > > minimize wheel re-inventing. > > (cut) > >=20 > > Makes sense. Could also be used for going in-between Muq servers. >=20 > True. I think the instant messaging people should be leveraging > MIME a lot more. Although in practice AOL and Microsoft between > them have pretty much killed off all the open-standards instant > messaging stuff anyhow. (snip) <http://www.jabber.org/> > It would be nice to extend mud paging, room conversations &tc to > use html and mime underneath at some point, if it could be done > without making things clumsy for the end-user. >=20 > Actually, I'd like to have the Muq compilers start eating HTML > (or some such) at some point, so we could start using true superscripts a= nd > such in our source code. Coding in ASCII is getting to be > pretty antique.=20 I don't agree, in this case. I think trying to edit write program code with HTML tags in an ASCII editor would be sufficiently painful to unjustify converting program code to HTML; specifically, the angled brackets come to mind. > > You know, it occurs to me, with the amount of code available in > > modules on CPAN, and with the easy OS access and processing/filtering > > of Perl, plus the efficiency, persistency, and multitasking VM of > > muq, that muq+perl could be a very powerful complementary combination. >=20 > I've been studying Perl (and to a lesser extent Python and Ruby) > somewhat seriously this year, after years of learning just enough > of a smattering to get by. >=20 > I agree that CPAN is a really rich lode of re-usable code that it > would be great to leverage for Muq. I've been thinking that when > it becomes an issue, it would make sense to write Perl subservers > for Muq, spawned off via ]rootPopenSocket, and then write just > teeny MUF wrappers to make all this transparent to the application > programming in softcode land. I've already wired up Muq <-> MUF glue <-> Perl glue <-> Lingua::EN::Inflect, actually. When I originally tried to do this with ProtoMUCK, it resulted in headaches from events between MUF processes not working right, then awful messing around with props and variables that couldn't be shared and synchronization and non-blocking-only sockets and timing and this and that and ... gack! And in the end there was still a weird bug where the program would rather than doing its I/O to the socket would unacceptably do so to the user. So I decided Proto wasn't going to suffice. :-) > If/when these kinds of libraries became heavily used, performance > issues might motivate rewriting them in Muq softcode, This depends on what kind of library it is, of course. > but in > general this seems like a great way to get functionality up fast > with a minimum of wheel-reinventing. (major time cheese) This is in fact what I meant by my comment. > More speculatively, a hack so that one could export the > Muq db as a Linux virtual file system would be potentially > cool, so one could go find/grepping &tc around the db. That does sound like an interesting idea. [removing whitespace-only lines] > > > > ---> Drake Wilson > > > Whee! :) > > *looks confused* Eh? > > > -- Cynbe > > ----> Drake Wilson > *grin* [/removing whitespace-only lines] (truncate) ? ----> Drake Wilson |
From: Drake W. <dr...@li...> - 2002-08-18 03:25:36
|
On Sat, Aug 17, 2002 at 07:02:30PM -0500, Cynbe ru Taren wrote: (snip) > > > 3) We select the .db file in which to place a package > > > by logging in as that user. > >=20 > > Sounds good to me -- rootAsUserDo{ ... } seems to do the trick. Whoops. No, it doesn't. From the root mufShell, on a (relatively) clean db: ((( root:=20 =2Eu["test"] root: #<User test b090700000007c95> rootAsUserDo{ "foo" inPackage @$s.package -> p [ "Name: %s\n DB: %s\n Owner: %s\n"=20 p$s.name p$s.dbname p$s.owner$s.name | ]print , [ " new Hash owner: %s\n" makeHash$s.owner$s.name | ]print , } Name: foo DB: ROOTDB Owner: root new Hash owner: root foo:=20 foo:=20 rootShutdown Closing db ROOTDB... ))) As you can see, the package changed into and the created hash are both owned by root and in ROOTDB, which IINM is not correct. On the other hand, with rootBecomeUser: ((( root:=20 =2Eu["test"] rootBecomeUser MUF (Multi-User Forth) shell starting up (Do muc:shell to start up Multi-User C shell.) test:=20 makeHash$s.owner$s.name test: "test" pop "foo" inPackage foo:=20 @$s.package -> p [ "Name: %s\n DB: %s\n Owner: %s\n" p$s.name p$s.dbname p$s.owner$s.name | ]print , foo: [ "Name: %s DB: %s Owner: %s " "foo" "test" "test" | Name: foo DB: test Owner: test foo:=20 ))) But it replaces the original shell, so there's no way to get back... ((( exitShell +-----------< Event >----------- | :event(1af5c000003d8e31) #<MosClass serverError 211fb00000618f55> | :formatString(1af5c0000042ce51) Needed dataStack argument at top-of-stack= [0] +------------------------------- +---------< Restarts >---------- +------------------------------- (Please enter a number, or else 'help' for help.) debug> ))) With no restarts, too -- oh no! This message is thus being cc'ed to muq-bugs, as the exitShell malfunction and the seemingly-useless rootAsUserDo{ } could probably be considered bugs. > > Indirectly related questions: Will putting users in a place other than > > .u (even, say, a subobject of .u) break anything? >=20 > Hrm. I'm not absolutely sure. I seriously doubt the C server will > care: The spirit of the Muq implementation is that nothing you can > do in softcode should break the hardcoded server. (I,e., put it in > an infinite loop or such, but not crash it.) This (the infinite loop) happened when I tried to create a second instance of Root, then login as it... the login job went into an infinite loop, seemingly eating memory along the way. > There may be some softcode such as the login routine that will > be surprised by your doing this. Doesn't matter, nobody will normally be logging into these users anyway. These "people" (digression: maybe if the package tool gets a lot of AI integrated it, the quotation marks will have to be removed?)=20 don't exist outside the system. > > And is it entirely > > impossible to log in as a user with a null-string > > $a.encryptedPassphrase? >=20 > Probably at the moment. Any system can develop security holes, > of course, and since Muq is by design policy-free at the C level, > it is easy to install security holes at the softcode level. =2E.. though one generally tries to avoid it. :-) > > *considers writing qpkg* >=20 > *cheers* :) Looking through the Debian packaging system for hints right now. > > Couldn't we just use ordinary cryptographic signatures for this? >=20 > Sure, but we still have to decide which kind of signature, where > to put it, how to find it, all that mundane stuff. >=20 > The RSA patent has expired so we can just use it if we want. You > can code up the basic RSA signature algorithm in Muq in about > half a dozen lines of code. Or use an external utility like PGP > off the shel if you prefer. PGP is what I was thinking, yes, though putting it directly in is probably faster (and otherwise better?). > The MIME standard(s) are another motherload we can mine for this > sort of stuff: They have both protocols and code for signing > arbitrary content. We might be able to leverage all that to > minimize wheel re-inventing. (cut) Makes sense. Could also be used for going in-between Muq servers. You know, it occurs to me, with the amount of code available in modules on CPAN, and with the easy OS access and processing/filtering of Perl, plus the efficiency, persistency, and multitasking VM of muq, that muq+perl could be a very powerful complementary combination. > > ---> Drake Wilson >=20 > Whee! :) *looks confused* Eh? >=20 > -- Cynbe ----> Drake Wilson |
From: Cynbe ru T. <cy...@mu...> - 2002-08-18 00:02:51
|
My replies inline. Drake Wilson <dr...@li...> writes: > On Fri, Aug 16, 2002 at 08:31:21PM -0500, Cynbe ru Taren wrote: > > I believe you're the first person to get this far before > > deciding the entry barrier to getting Muq to do something > > useful was just too high to be worth the effort. > > Too high? Huh? > > *looks up at entry barrier, twists head around to look back at wings, > flexes them once to make sure they still work, then turns back to > Cynbe and blinkblinks* > ;-P *laugh*! > Seriously, though, Muq seems like a good platform for what I want to > do (consensus-based text VR), and so rather than give up on it and > wander around aimlessly and endlessly looking for a better option, I'd > prefer to stick with it, fixing, working around, or asking about fixes > or workarounds for, the little things that get in the way. This is certainly a viable plan... > > 3) We select the .db file in which to place a package > > by logging in as that user. > > Sounds good to me -- rootAsUserDo{ ... } seems to do the trick. > Indirectly related questions: Will putting users in a place other than > .u (even, say, a subobject of .u) break anything? Hrm. I'm not absolutely sure. I seriously doubt the C server will care: The spirit of the Muq implementation is that nothing you can do in softcode should break the hardcoded server. (I,e., put it in an infinite loop or such, but not crash it.) There may be some softcode such as the login routine that will be surprised by your doing this. > And is it entirely > impossible to log in as a user with a null-string > $a.encryptedPassphrase? Probably at the moment. Any system can develop security holes, of course, and since Muq is by design policy-free at the C level, it is easy to install security holes at the softcode level. > *considers writing qpkg* *cheers* :) > Couldn't we just use ordinary cryptographic signatures for this? Sure, but we still have to decide which kind of signature, where to put it, how to find it, all that mundane stuff. The RSA patent has expired so we can just use it if we want. You can code up the basic RSA signature algorithm in Muq in about half a dozen lines of code. Or use an external utility like PGP off the shel if you prefer. In Bruce Schneier's crypto book, he points out that RSA signatures have turned out to be just one of a family of related algorithms, some of which are a bit simpler and easier to code up than RSA. The MIME standard(s) are another motherload we can mine for this sort of stuff: They have both protocols and code for signing arbitrary content. We might be able to leverage all that to minimize wheel re-inventing. Muq currently assigns every user a public/private key pair and uses this to transparently secure (validate and encrypt) muqnet interactions using twofish symmetric encryption and Diffie-Hellman key exchange. For at least some RSA style public key systems, we can use the same public/private key pair for RSA signatures as well as Diffie-Hellman key exchange. > ---> Drake Wilson Whee! :) -- Cynbe |
From: Drake W. <dr...@li...> - 2002-08-17 05:06:27
|
On Fri, Aug 16, 2002 at 08:31:21PM -0500, Cynbe ru Taren wrote: >=20 > My comments inline: >=20 > Drake Wilson <dr...@li...> writes: >=20 > > In 030-C-struct.muf.t, I see: > > > "muf" inPackage > >=20 > > How does muq-db-c (or related subprocesses) know to put this library > > in the "MUF" database? And (how) is it possible to use this feature > > myself? Putting my miscellaneous custom libraries in a "FOO" (or, > > "foo" -- which is recommended?) database would be nice, but is awkward > > because of having to put a new file in to create the database. >=20 > You -are- persistent! :) :-) > I believe you're the first person to get this far before > deciding the entry barrier to getting Muq to do something > useful was just too high to be worth the effort. Too high? Huh? *looks up at entry barrier, twists head around to look back at wings, flexes them once to make sure they still work, then turns back to Cynbe and blinkblinks* ;-P Seriously, though, Muq seems like a good platform for what I want to do (consensus-based text VR), and so rather than give up on it and wander around aimlessly and endlessly looking for a better option, I'd prefer to stick with it, fixing, working around, or asking about fixes or workarounds for, the little things that get in the way. (claw) > So I thought on balance the best way to handle the issue > was to mandate user=3D=3Ddb: One .db per user, and one user > per .db, in general. This is simple, it does the right > thing 90% of the time, it sweeps all the .db issues > under the rug for the typical user, and the sysadmin > (who we suppose can handle a bit more complexity) can > create one fictitious "user" per unique system library > that s/he wants in a separate .db file. > > So the short answer to your question runs so. The > intention is >=20 > 1) There is one logical .db per user. >=20 > 2) We create extra fictional 'users' for libraries > and packages which we want in separate .db files, > for independent distribution. >=20 > 3) We select the .db file in which to place a package > by logging in as that user. Sounds good to me -- rootAsUserDo{ ... } seems to do the trick. Indirectly related questions: Will putting users in a place other than =2Eu (even, say, a subobject of .u) break anything? And is it entirely impossible to log in as a user with a null-string $a.encryptedPassphrase? (claw) > > Also, distributing libraries, I suppose, should be done in both dbfile > > and source format; however, how the source files should be organized > > in a MUF library distribution seems to be currently undefined -- > > coordinating three-digit numbers across all MUF library developers may > > be reasonable now, but doesn't scale well at all. I should write some > > installation scripts to help with this, but I'd like feedback on how > > the sources should be organized before I start anything. > >=20 > > ---> Drake Wilson >=20 > You're exactly right. >=20 > In the long run, I'd like to have the source code retained > in the compiled packages, and have the .db files be the > preferred distribution unit. (warp) This would be much preferable, yes. > I think that is mostly 'requires', > 'conflicts' &tc relationships between packages, plus > pre/post install/remove scripts, but I haven't looked > carefully at this problem. That sounds about right. *considers writing qpkg* > Then we should steal those > wheels for the Muq .db situation, plus do some things right > from the very start such as having proper signatures to > validate .dbs as being from who they say they are. (warp) Couldn't we just use ordinary cryptographic signatures for this? > Anyhow, that's sort of where we are. This is one of > those fronts on which (imho) Muq has at least a pretty > good first cut at a solution, where other systems have > yet to even arrive at the question, really. > > Was any of that in the least intelligible? :) Yes, very, and informative too. :-) >=20 > -- Cynbe (truncate) ---> Drake Wilson |
From: Cynbe ru T. <cy...@mu...> - 2002-08-17 01:31:27
|
My comments inline: Drake Wilson <dr...@li...> writes: > In 030-C-struct.muf.t, I see: > > "muf" inPackage > > How does muq-db-c (or related subprocesses) know to put this library > in the "MUF" database? And (how) is it possible to use this feature > myself? Putting my miscellaneous custom libraries in a "FOO" (or, > "foo" -- which is recommended?) database would be nice, but is awkward > because of having to put a new file in to create the database. You -are- persistent! :) I believe you're the first person to get this far before deciding the entry barrier to getting Muq to do something useful was just too high to be worth the effort. The multi-db support was one of the last things I put into Muq: much of the 10th year of development was devoted to it (along with making the .db files portable between 32 and 64 bit and big/little endian machines). As a user of TinyMUCK, and an administrator of a >kilouser virtual world, I was really sick of the pain and mess involved in installing system library updates, in moving a user's data from one server to another, &tc &tc. I wanted something cleaner, and I couldn't find any very good prior art (other than Unix disk partitions, which can be un/mounted, moved between systems &tc), so I had to pretty much roll my own. This is one thing which I don't think MOO, Smalltalk, Lisp, or any of the similar systems I've looked at address at all well. We already had packages, and Occam's Razor suggested db==package as the first try, to keep things simple, but upon consideration, that just didn't seem practical. One will often want lots of little packages for namespace cleanliness without wanting to have a separate db file for every damn little one of them, especially with the dangers that poses of loading a mixture of .db files which don't really belong together. I/we could have set up an 'inDb' &tc series of operators parallel to the existing 'inPackage' &tc series, but that seemed like too much of a good thing, to me. Muq already has enough stuff to learn without users having that batch of operators thrown at them as well. So I thought on balance the best way to handle the issue was to mandate user==db: One .db per user, and one user per .db, in general. This is simple, it does the right thing 90% of the time, it sweeps all the .db issues under the rug for the typical user, and the sysadmin (who we suppose can handle a bit more complexity) can create one fictitious "user" per unique system library that s/he wants in a separate .db file. So the short answer to your question runs so. The intention is 1) There is one logical .db per user. 2) We create extra fictional 'users' for libraries and packages which we want in separate .db files, for independent distribution. 3) We select the .db file in which to place a package by logging in as that user. One nice side-effect of this system is that since Muq automatically assigns every user a unique private and public key, every separately distributable .db file has its own public/private key identity, which can be used for signing / validating / &tc releases. This does require that we not distribute the private key as part of the package, of course... :) Since these facilities have never been tested in a production environment, just coded up based on my experience in a production environment, there are undoubtedly some rough edges to be smoothed out. But I think we have basically a pretty workable concept here -- a sound foundation on which to build. And that's what I was trying to get in place for release 0.0.0. It may be that in the long run this "db==user" concept will prove too simplistic, and we'll have to add something like "inDb" operators to the virtual machine. But it is much better to start too simple and then add stuff as needed, than to start out too complex -- since it is extremely hard to remove functionality from a virtual machine once it is in reasonably wide use. ForTran had "deprecated" a lot of stuff over the last half century, but last I heard they had still never actually removed anything from the language. Just too much risk of huge, ancient programs breaking as a result. > Also, distributing libraries, I suppose, should be done in both dbfile > and source format; however, how the source files should be organized > in a MUF library distribution seems to be currently undefined -- > coordinating three-digit numbers across all MUF library developers may > be reasonable now, but doesn't scale well at all. I should write some > installation scripts to help with this, but I'd like feedback on how > the sources should be organized before I start anything. > > ---> Drake Wilson You're exactly right. In the long run, I'd like to have the source code retained in the compiled packages, and have the .db files be the preferred distribution unit. And to have a squeak-like interactive programming environment within Muq for coding in style. :) In the short run, the compiler doesn't retain source code, I don't think (people were bugging me about the .db files being too big for their taste) and we don't have the above sort of programming environment yet, so distributing source separately is the most practical idea, I think, and then distributing .db files for the things that don't make sense to distribute as source, such as chunks of living worlds. The numbering system is of course a hack, pure and simple. I could have taken time to write a full-blown package management system, but I thought 10 years before first beta was already long enough, and that this was one example of a problem where a quick-and-dirty fix would do fine initially: It isn't committal, so we can go back and retrofit something more sophisticated later without breaking backward compatability. (My mantra for the last year or two of Muq pre-beta development was to work on only those things which would break backwards compatability if I did them after first beta.) In my opinion (no doubt biased, since I'm a heavy Debian Linux user) the Debian package system is the most successful, well-tested prior art which we can rely on on this front. It is possible that we should figure out a way to use the existing Debian package infrastructure as is, rather than re-inventing that wheel. But I expect that will prove awfully awkward and unpleasnt, and that we'll want to craft something more suited to Muq and the virtual world environment. If so, we should study and steal what makes .deb files work well in terms of fundamental structure. I think that is mostly 'requires', 'conflicts' &tc relationships between packages, plus pre/post install/remove scripts, but I haven't looked carefully at this problem. Then we should steal those wheels for the Muq .db situation, plus do some things right from the very start such as having proper signatures to validate .dbs as being from who they say they are. For the moment, just having the build scripts load the source files in alphabetic order and then using the current numbering scheme to (crudely!) express dependency relationships between them is a very cost-effective way to get started: It takes virtually no coding and gets the job done for now. My next planned short-term improvement on that front was to break up the contents of muq/pkg into subdiretories, one per logical system (such as system libraries, virtual world server &tc). There are some only semi-resolved issues involving cross-references between .db files. The current logic does, I believe, a good job of not crashing hard in the case of dangling links &tc, but what is lacking is a clear contract between consumer and producer packages: What should each of them do to ensure that the system keeps working sanely after a library update? If you rebuild a library from scratch and everything has a different identity, how do links from the client .db files find the intuitively proper destination? My interim answer for now is that client packages should only maintain pointers to package symbols in producer libraries, and maintainers of producer libraries should be at pains to never destroy and recreate such symbols. (Or the package objects in which they live.) The producer library maintainer is, however, free to destroy and recreate any other objects in the .db file as part of maintainance, and the consumer library which stores pointers to them -will- break and has nothing to blame but itself. For a Generation II version of the .db filesystem support in Muq, I'd like to go a bit further than this. Without making any hard and fast promises, I would like it to make a good-faith effort to do significantly better than the above. Specifically, when you unmount a .db file, I would like the server to essentially convert "forbidden" cross-pointers from other .dbs into the interior of the dismounted .db with the moral equivalent of unix filesystem symlinks where-ever possible: It will search for a path from the root package on the .db to the referenced object, and replace the forbidden hard link with a symlink-like proxy object if possible. This way, when an updated version of the dismounted .db is mounted in place of it, the converted crosslinks can (often) still be resolved to the appropriate object (even if its low-level binary identifier is now different). (Perhaps I should mention that the current implementation already guards such cross-links with an 8-bit or so generation number, so that with moderately probability, dangling links get detected and resolved to something like NIL links. Even in the cases where this safety-measure fails, there shouldn't be any C-server level crasher bugs, just some unexpected stuff going on in softcode.) Anyhow, that's sort of where we are. This is one of those fronts on which (imho) Muq has at least a pretty good first cut at a solution, where other systems have yet to even arrive at the question, really. Was any of that in the least intelligible? :) -- Cynbe |
From: Drake W. <dr...@li...> - 2002-08-16 05:46:48
|
In 030-C-struct.muf.t, I see: > "muf" inPackage How does muq-db-c (or related subprocesses) know to put this library in the "MUF" database? And (how) is it possible to use this feature myself? Putting my miscellaneous custom libraries in a "FOO" (or, "foo" -- which is recommended?) database would be nice, but is awkward because of having to put a new file in to create the database. Also, distributing libraries, I suppose, should be done in both dbfile and source format; however, how the source files should be organized in a MUF library distribution seems to be currently undefined -- coordinating three-digit numbers across all MUF library developers may be reasonable now, but doesn't scale well at all. I should write some installation scripts to help with this, but I'd like feedback on how the sources should be organized before I start anything. ---> Drake Wilson |
From: Andrew B. <an...@wi...> - 2001-08-30 21:39:47
|
On Thu, Aug 30, 2001 at 01:41:40PM -0700, Rayanth Drygu wrote: > One other problem I noticed but didn't mention, was in the actual MUF coding > and documentation... in the documentation it mentions how to create a > function, but it never says how to delete it. Is it possible to delete > functions ? I know they're stored in the database after creation, so they > don't just go away.... But in my playing aroudn with the MUF stuff, I > created lots of functions that I'd like to remove now, and I can't find a > way of deleting them!! Deleting things is an 'intermediate user' topic, based on the fact that everything you need seems to be described in the intermediate MUF tutorial, and you have to squirrel around a bit to find it out. Look up the 'Understanding Packages' section for details. In fact, it's very easy to do: just type: > 'funcname unintern The single apostrophe IS important. Here's some info about what's going on (as I understand it)... Let's pretend you've created a 'hw' function as root: root: > : hw "Hello world!\n" , ; What this does is it creates a compiledFunction object, and stores it in the 'function' property of a 'hw' symbol. You can see all of this if you start prodding about under the covers: > 'hw root: 'hw(e5ac31) > ls :function(1af5c00000000cb1) #<compiledFunction hw 12ab3d7> :type(1af5c00000008db1) nil(4ef1) :proplist(1af5c0000000ad71) nil(4ef1) :package(1af5c0000000cd51) #<Package root 21fd5> :name(1af5c0000000ed31) "hw" > 'hw.function call Hello world! > @$s.lib["root"] lsh "checkVersion" 'checkVersion(d8ae11) "hw" 'hw(e5ac31) That last line shows what Muq might be doing when you try looking up the 'hw' symbol. @$s.lib contains the list of packages that the current job (or user) has access to. We are working in the "root" package (hence the 'root:' prompt - play with 'inPackage' to change this). The package itself is just a dictionary of symbol names: by default, symbols are created as hidden properties so that other people can't see them. You have to 'export' symbols to make them publicly visible. The 'unintern' function just removes the named symbol from the current package, and Muq's garbage collector will subsequently remove the symbol and function objects. > I'll consider your suggestions, Andrew, though most of that is not in my > hands - I'm just a tester / documentation guy, not a coder =) We'll see what Cynbe has to say about the ideas... Cheers, Andrew -- Permission is hereby granted for you to use this signature in your own messages, subject to the following conditions: a) you must not modify it in any way; b) you may not grant other people the right to copy it. |
From: Rayanth D. <ra...@si...> - 2001-08-30 20:38:04
|
Caught up in the midst of moving myself to another apartment on short notice, and moving toa new hosting company for my dedicated server, I've once again put my work with Muq on hold for a little bit =) I'll get around to it eventually...once I've settled in at a new job (which I haven't found yet) and the new apartment. One other problem I noticed but didn't mention, was in the actual MUF coding and documentation... in the documentation it mentions how to create a function, but it never says how to delete it. Is it possible to delete functions ? I know they're stored in the database after creation, so they don't just go away.... But in my playing aroudn with the MUF stuff, I created lots of functions that I'd like to remove now, and I can't find a way of deleting them!! I'll consider your suggestions, Andrew, though most of that is not in my hands - I'm just a tester / documentation guy, not a coder =) - RAyanth > -----Original Message----- > From: muq...@li... > [mailto:muq...@li...]On Behalf Of Andrew Bolt > Sent: Thursday, August 30, 2001 1:35 PM > To: muq...@li... > Subject: Re: [Muq-coder] Compiling Muq > > > Hi Rayanth, > > I hope you managed to sort out the compilation problems in the end. > > On Sun, Aug 12, 2001 at 12:45:45AM -0700, Rayanth Drygu wrote: > > I especially believe that the necessity of editing .cshrc (or, > for *most* > > Linux systems, which is likely to be the majority of the Muq > base, the bash > > shell is the prominent shell, and thus the .profile and/or > .bashrc instead > > of .cshrc) needs to be completely removed. I have never compiled another > > program of any type that required adding paths to my shell > configuration. > > I guess the main reason for needing to set the PATH is because Muq's > 'make install' doesn't copy the executable into /usr/local/bin and > create a default database somewhere under /var. May be this could > be made the default behaviour, so that people who just want to get > up and running can do so without reading anything? Users who want > the current behaviour (running Muq in a user directory rather than > as a system program) could still pass a -prefix option to the Configure > stuff. > > This should also make it possible to remove the assumption that you > are compiling from the home directory. That said, you should keep > all the documentation explaining how to install Muq under ~/ > because I definitely prefer working that way. > > > Some other problems I've noticed: > > The Sourceforge project only has muq-0.0.0 available for download, > but muq-0.0.3 is available from the ftp server. May be you should > find an excuse to make a 0.0.4 release and put that under the > Files list, so that it doesn't look like the project is totally > stagnant (it isn't, is it?) > > make check reports three errors, instead of the expected two: > > ------------------------------ > --- ERROR RECAP --- > --- 3992 TESTS PASSED --- > --- 3 ERRORS FOUND --- > ------------------------------ > ***** Failed test 28 because: Execution failed. > ***** Failed test 29 because: Execution failed. > ***** Failed test 175 because: Didn't return TRUE value. > -- NOTE! -- Tests 28 and 29 SHOULD fail, at present. > > ...and the INSTALL docs say that tests 46 and 47 should fail. > > The INSTALL docs also refer to '$muqhome', after telling you > to set the 'MUQDIR' environment variable. It might be better > to set $MUQHOME up front, and then refer to $MUQHOME/... > thereafter, instead of '~/muq/...'. > > > Cheers, > > Andrew > -- > Permission is hereby granted for you to use this signature in your own > messages, subject to the following conditions: a) you must not modify it > in any way; b) you may not grant other people the right to copy it. > > _______________________________________________ > Muq-coder mailing list > Muq...@li... > http://lists.sourceforge.net/lists/listinfo/muq-coder > > |
From: Andrew B. <an...@wi...> - 2001-08-30 20:28:49
|
Hi Rayanth, I hope you managed to sort out the compilation problems in the end. On Sun, Aug 12, 2001 at 12:45:45AM -0700, Rayanth Drygu wrote: > I especially believe that the necessity of editing .cshrc (or, for *most* > Linux systems, which is likely to be the majority of the Muq base, the bash > shell is the prominent shell, and thus the .profile and/or .bashrc instead > of .cshrc) needs to be completely removed. I have never compiled another > program of any type that required adding paths to my shell configuration. I guess the main reason for needing to set the PATH is because Muq's 'make install' doesn't copy the executable into /usr/local/bin and create a default database somewhere under /var. May be this could be made the default behaviour, so that people who just want to get up and running can do so without reading anything? Users who want the current behaviour (running Muq in a user directory rather than as a system program) could still pass a -prefix option to the Configure stuff. This should also make it possible to remove the assumption that you are compiling from the home directory. That said, you should keep all the documentation explaining how to install Muq under ~/ because I definitely prefer working that way. Some other problems I've noticed: The Sourceforge project only has muq-0.0.0 available for download, but muq-0.0.3 is available from the ftp server. May be you should find an excuse to make a 0.0.4 release and put that under the Files list, so that it doesn't look like the project is totally stagnant (it isn't, is it?) make check reports three errors, instead of the expected two: ------------------------------ --- ERROR RECAP --- --- 3992 TESTS PASSED --- --- 3 ERRORS FOUND --- ------------------------------ ***** Failed test 28 because: Execution failed. ***** Failed test 29 because: Execution failed. ***** Failed test 175 because: Didn't return TRUE value. -- NOTE! -- Tests 28 and 29 SHOULD fail, at present. ...and the INSTALL docs say that tests 46 and 47 should fail. The INSTALL docs also refer to '$muqhome', after telling you to set the 'MUQDIR' environment variable. It might be better to set $MUQHOME up front, and then refer to $MUQHOME/... thereafter, instead of '~/muq/...'. Cheers, Andrew -- Permission is hereby granted for you to use this signature in your own messages, subject to the following conditions: a) you must not modify it in any way; b) you may not grant other people the right to copy it. |
From: Rayanth D. <ra...@si...> - 2001-08-12 07:41:41
|
A serious change needs to be made to the method of compilation. I am not a Linux guru, but there are some things that I know that should be done because they are more or less the unofficial standard for compiling, and are simple and straightforward. I especially believe that the necessity of editing .cshrc (or, for *most* Linux systems, which is likely to be the majority of the Muq base, the bash shell is the prominent shell, and thus the .profile and/or .bashrc instead of .cshrc) needs to be completely removed. I have never compiled another program of any type that required adding paths to my shell configuration. Secondly, it should not be assumed that a user is compiling Muq from their home directory. I believe the assumption at current is $HOME/muq/c being the source dir. This is not a very wise assumption, and is likely to be more often wrong than right. Following the INSTALL directions word-for-word, I attempted to compile Muq in a directory other than my home. Specifically, I was in system root ( / ) when I extracted the tar.gz archive, therefore Muq root was /muq, source was /muq/c and bin would be /muq/bin. Following the directions to the letter, I edited my .profile (bash, as stated before, is the default shell for almost all Linux systems), and ran make from /muq/c . Configure ran fine (except for a problem with rm, not sure what it was... says "no such option -L") but as soon as it started compiling, it was still trying to look for the header files somewhere under /home/rayanth/muq.... Now, i specifically added the supposedly necessary changes to my .profile, re-ran the profile, even logged out and back in, and still get the same thing. This should not be happening. almsot every program I've compiled, including countless different MU* codebases, find the necessary directories by searchign for them based on the current directory. If i run .configure from /muq/c, for instance, it will go back to /muq, and find /muq/bin and /muq/h and make note of that. This is the way every program I've ever compiled does it, and this is how I believe Muq should do it too. As stated at the beginning of this email, I am not a linux guru, nor am I much of a programmer. I'm not up tot eh task of attempting to edit a Makefile to replace ll of teh necessary paths with the proper path - .configure's main chore is to do this for me, so I shouldn't have to be a linux guru to do it. Also, it sounds like the path changes should be put into .bashrc as well as, if not instead of, .profile for bash systems.... is this the case ? .bashrc sounds a lot more like .cshrc, and all the changes went to .cshrc by default for the INSTALL directions.... did someone (Cynbe ? =) not type it correctly ? Has installation even been tested on bash by anybody, and this problem was not caught ? Please don't take any of the above as offensive - it was not intended that way. More like constructive criticism.... it's also 12:45am when I'm writing this, having just gotten home from work =) Food for thought. Please reply with any repsonses you might have - either agreeing with me, or explaining why it was done the way it was instead of the more or less standard way - Rayanth Drygu |
From: Nolan D. <no...@bi...> - 2001-05-08 16:27:03
|
>>>>> "Andrew" == Andrew Bolt <an...@wi...> writes: Andrew> So, does anyone know if anyone else has tackled this sort Andrew> of thing before - and does anyone else thing anything good Andrew> could come out of this? I had some ideas about this. Unfortunately most of my mud work has been put aside because of school and work, but since I'm about to take a break from both, some additional work may get done. :) I've been working on a Muq XML parser for the past year, but I'm working very very sloooowly. :) It's meant to be an expat-like event-based parser. Once the parser is implemented, I'd like to write a Muq implementation of Atlas, the client used by the Worldforge (http://www.worldforge.org/) project. While this protocol wouldn't be as elegant as the format you discussed, it does have some advantages for the environment which I'm trying to create. Anyhow, if you're interested, I could send my XML parsing code to you or to the list at large. ATM it supports <tag></tag>, <tag/>, <tag>ctext</tag>, etc. Attributes and comments are next on my list of supported features, followed by < > & '. I'm not good enough at parsing to write support for stylesheets, external declarations, etc. If anyone wants to help with this, or, if anyone can finish it off, then let me know. :) I'd like to put this behind me and work on something a bit more interesting, such as the atlas code. |
From: Andrew B. <an...@wi...> - 2001-05-08 15:20:23
|
Hi peeps, I've just started getting into XML and associated protocols. Seems to be a lot of good ideas coming up... some of them look like they could be fun to play with in a MUD environment, and Muq would seem to be an excellent vehicle for playing around with this sort of thing. I've tried looking for evidence of XML usage in the MUD community. So far, I've found the following: Zuggsoft's MXP protocol, which is intended to be a better way of connecting client and server than telnet. See: http://www.zuggsoft.com/zmud/mxp.htm A MOO-binding for Expat, an XML parser. Here are my own ideas: Firtly, have the server send all its text to the client as XML - possibly looking something like this: <room> <name>A long hallway</name> <picture src="xmptr3294.jpg"/> <description> <p>You are in a <emph>long</emph> <exit name="north">north</exit>-<exit name="south">south</exit> hallway.</p> <p>There is a <exit name="west">door</exit> to the west.</p> </description> <object name="cat"> A cat eyes you cautiously. </object> </room> Using style-sheets, a generic client could render this in whatever way is appropriate. It would almost be possible to use a latest generation web-browser (with CSS+XML support), if it weren't for the fact that you want your MUD experience to be a single, continuous session instead of a series of separate pages... but I'm sure it wouldn't take much hacking to get the Mozilla rendering engine to do this. It might still be possible to use http for the session (with the connection being kept permanently open between requests). You could even allow the server to redirect the client to a different server mid-session completely transparently. Where things would get more fun would be if you embedded higher-level semantic information in the XML: for example, <object name="cat"> <picture src="auibr3284.jpg"> <action name="stroke"/> </object> An enhanced graphical client could then display a 'stroke' button underneath an icon representing the cat. Clicking this could generate a pseudo XML-RPC request: <methodCall target="cat"> <methodName>stroke</methodName> </methodCall> All sorts of fun and interesting possibilities spring to mind... So, does anyone know if anyone else has tackled this sort of thing before - and does anyone else thing anything good could come out of this? Cheerio, Boro -- "96234223420239212224212022201022921222331202121112195321202232242192627082"v >"_",\1- v v-9:_ v#:-*86_@#:\< 0"122282229122223222233917120212222202912"< |:\_$#:!#<v#_1+,!1>\!\ 1+ >|1, < This space reserved > "19202222224122"^ >" ",\1- ^>: #B#E#F#U#N#G#E# ^>"/"^ for messages. Andrew ^"2222413132399124"< |
From: Cynbe ru T. <cy...@mu...> - 2001-03-01 03:05:31
|
I've done nada except jot a few notes to myself in muq/c/Projects. I need a heads-up display so I can code while commuting *wrygrin*. Once our California house sells, I'm expecting to move back to Austin, live with my wife, telecommute 4 days/week to Cisco, and have a life again, including time to work on Muq. House sales, however, involve statistics of small numbers, so precise planning isn't possible. We seem to be past the Christmas lull and getting people coming around for second, third, and fourth looks, so I'm mildly hopeful of a serious offer before the end of March. In reply to Eli's query, the SourceForge version is the definitive public Muq release at present. I've neither lost nor done anything with the parallel-build patch. You're free to check it into SourceForge CVS and do a release if you like. :) Meanwhile, I'm culturing virii in my lungs. Ah, the joys of winter! :) -- Cynbe PS: I presume everyone has seen the obits announcing Claude Shannon's death. Another great one gone. :( I'm finding information theory steadily more useful over time, and boolean theory steadily less so... I think Claude's star will keep rising for a long time yet, as his contributions become steadily more widely appreciated and applied. Scott A Crosby <cr...@qw...> writes: > Hi.. It's been a while since the last email and the last status report on > MUQ. > > So, what is the status of various projects? What direction are they going > in? ['dead' is a valid status] > > Also, Cynbe, what's the status with my parallel-build patch and a few > other things I've done. I hope you haven't lost it like you've lost > another half-dozen patches I've sent. > > Scott > > > > -- > No DVD movie will ever enter the public domain, nor will any CD. The last CD > and the last DVD will have moldered away decades before they leave copyright. > This is not encouraging the creation of knowledge in the public domain. > > > _______________________________________________ > Muq-coder mailing list > Muq...@li... > http://lists.sourceforge.net/lists/listinfo/muq-coder |
From: Eli S. <wic...@wi...> - 2001-02-28 00:07:06
|
----- Original Message ----- From: "Scott A Crosby" <cr...@qw...> To: <muq...@li...> Sent: Tuesday, February 27, 2001 5:08 PM > So, what is the status of various projects? What direction are they going > in? ['dead' is a valid status] The Win32/UWin 2.x port is currently 'dormant' ('dead' implies something so much more certainly final :). As I now have a Linux box next to me and a ton of homework, the drive to spend more time fiddling with it is very low. ;) If anyone else wants to give it a go, shoot me an email and I will help how I can though. :) Aside, I tried to find a .tar with all the latest patches and revisions (isn't Muq up to 0.0.29 or something?), but I could not get ahold of one. Where are the latest files stashed ATM? Anywhere? SourceForge? Thanks... Eli |
From: Scott A C. <cr...@qw...> - 2001-02-27 23:06:55
|
Hi.. It's been a while since the last email and the last status report on MUQ. So, what is the status of various projects? What direction are they going in? ['dead' is a valid status] Also, Cynbe, what's the status with my parallel-build patch and a few other things I've done. I hope you haven't lost it like you've lost another half-dozen patches I've sent. Scott -- No DVD movie will ever enter the public domain, nor will any CD. The last CD and the last DVD will have moldered away decades before they leave copyright. This is not encouraging the creation of knowledge in the public domain. |
From: Cynbe ru T. <cy...@mu...> - 2001-01-08 21:00:09
|
Yes, scopes that don't get closed are not well diagnosed by the current MUF compiler. (To put it mildly!) Perhaps a warning should be issued if a left-justified ':' is encountered while 'inside' a function definintion -- this might diagnose most such errors much more clearly. I've added that idea to my 'muq/c/Bugs' file, anyhow. Doing a really good (or even half-decent) job reporting these sorts of errors is one of the things that separates a production-quality compiler from a first-beta one. :) As a personal update, I spent 1100 hours commuting to Cisco last year :( but I'm expecting to go over to almost entirely telecommuting sometime this year, plus cut back from 40 to 32 hours of "official" worktime/week -- when this happens, my Muq timeslot should go from essentially zero back to something useful -- Cynbe Nolan Darilek <no...@bi...> writes: > I spotted my error. Seems I was a bit too enthusiastic when > cut-n-pasting some earlier code. > > > Anyhow, the problem seems to be caused by functions which aren't ever > closed, and the initialization process doesn't report this. Has anyone > else encountered this? > > _______________________________________________ > Muq-coder mailing list > Muq...@li... > http://lists.sourceforge.net/mailman/listinfo/muq-coder |
From: Nolan D. <no...@bi...> - 2000-12-30 02:48:05
|
I'm continuing to work on my Muq XML parser. I've recently added cdata support, and once I add support for attributes I'll have a fairly usable subset of XML parsable. I'm having more issues, though. Today I rm'd my database directory and used muq-db to rebuild the database. But muq-db hangs when it encounters my XML parsing code. It simply hangs and doesn't produce an error message. Here's what I get in muq.log: date:2000/12/29/17:58:26.903 muq:127.000.000.001:30000 job:0000000000a9de75 user:root msg: 213-millisec garbage collect #63 recovered 515 objects 61710 bytes, left 25950 objects, 3652197 bytes date:2000/12/29/17:58:28.302 muq:127.000.000.001:30000 job:0000000000a9de75 user:root msg: 217-millisec garbage collect #64 recovered 499 objects 66745 bytes, left 26224 objects, 3685496 bytes date:2000/12/29/17:58:29.370 muq:127.000.000.001:30000 job: user:root msg: skt_read_tcp_socket: read 0 bytes so calling usually_start_closing_socket... date:2000/12/29/17:58:29.372 muq:127.000.000.001:30000 job: user:root msg: skt_read_tcp_socket: read 0 bytes so calling usually_start_closing_socket... date:2000/12/29/17:58:29.372 muq:127.000.000.001:30000 job: user:root msg: >>> Out of batch files setting state to SKT_DRAINING_INPUT at now d=978134309372 time(NULL) d=978134309 I'll include the code below, to see if anyone else can reproduce this. What could be causing this hang? I'm sure I have a loose ; or something which I'm just not seeing. :) -------------------------------------------------------------------------------- @example @c "XML" rootValidateDbfile pop [ "xml" .db["XML"] | ]inPackage ( See MYURL for extensive documentation about this package's implementation. ) ( inner -- Are we within elements? If so, CDATA is supported. ) nil --> inner ( XMLParser -- Stores information about which functions to call and when. ) defclass: XMLParser ; 'XMLParser export defgeneric: startElementHandler { $ $ -> $ } ; defgeneric: endElementHandler { $ $ -> $ } ; defgeneric: CDATAHandler { $ $ -> $ } ; defgeneric: CommentHandler { $ $ -> $ } ; ( Here we build a test XML parser. ) defclass: TestXMLParser :isA 'XMLParser ; defmethod: startElementHandler { 'TestXMLParser 't } -> element -> parser element , " opens\n" , parser ; defmethod: endElementHandler { 'TestXMLParser 't } -> element -> parser element , " closes\n" , parser ; defmethod: CDATAHandler { 'TestXMLParser 't } -> cdata -> parser cdata , " appears\n" , parser ; ( |CDATState -- Handle CDATA ) : |CDATAState { [] $ -> [] $ } -> parser "" -> cdata ( Keep grabbing chars until we hit a <. ) |pop -> ch do{ '<' ch = not while cdata ch charString join -> cdata |pop -> ch } parser cdata CDATAHandler -> parser ch |push parser nil --> inner ; ( |endElementState -- Transition to this state when |startElementState ) ( encounters a '/'. ) : |endElementState { [] $ $ -> [] $ $ } ( Grab our parser and element stack. ) -> parser -> elements ( Initialize the variable holding our local element. ) "" -> element ( Loop through the string until '>' or ' ' is hit. ) |pop -> ch do{ ch '>' = not ch ' ' = not and while element ch charString join -> element |pop -> ch } ( Maybe we can't close this element. ) element elements pull = not if element " is not the last open element." join error fi ( Add callback here later. ) parser element startElementHandler -> parser : |endElementState { [] $ $ -> [] $ $ } ( Grab our parser and element stack. ) -> parser -> elements ( Initialize the variable holding our local element. ) "" -> element ( Loop through the string until '>' or ' ' is hit. ) |pop -> ch do{ ch '>' = not ch ' ' = not and while element ch charString join -> element |pop -> ch } ( Maybe we can't close this element. ) element elements pull = not if element " is not the last open element." join error fi ( Add callback here later. ) parser element endElementHandler -> parser elements parser ; ( |startElementState -- Transition to this state when we've found an element. ) : |startElementState { [] $ $ -> [] $ $ } ( Grab the parser and elements stack. ) -> parser -> elements ( Special handling for |endElementState ) |pop -> ch ch '/' = if elements parser |endElementState return fi ( Initialize our lastElement variable. ) "" -> lastElement ( Collect all characters in this element. ) ( Loop through the string until '>', '/' or ' ' is hit. ) do{ ch '>' = not ch ' ' = not and ch '/' = not and while lastElement ch charString join -> lastElement |pop -> ch } lastElement elements push do{ ch ' ' = while |pop -> ch } parser lastElement startElementHandler -> parser elements parser ( Kinda hacky, but this handles the /> element closing. ) ( First get rid of extra spaces. ) '/' ch = if -> parser -> elements |pop -> ch ch '>' = if lastElement ">" join stringChars[ |reverse ]|join elements parser |endElementState else ch " cannot follow '/' when closing elements." join error fi fi t --> inner ; : ]initialState { [] $ -> } -> parser makeStack -> elements do{ |length 0 > while ( Grab our character. ) |pop -> ch ( ' ' -- continue. ) ch ' ' = if loopNext fi '<' ch = if elements parser |startElementState -> parser -> elements loopNext fi ch alphaChar? inner and if ch |push parser |CDATAState -> parser loopNext fi ( Error if we've made it here. ) ch charString " not valid in top-level XML." join error } ]pop ; : parse { $ $ -> } ( Grab our parser and string. ) -> parser -> string ( Split it and call into the state machine for parsing. ) string stringChars[ |reverse parser ]initialState ; 'parse export @end example -------------------------------------------------------------------------------- |