3 ms·
On the surface, this: > With a MOP, however, you can still have this more compact data representation format (since the data is sparse), but still have all the
by brundolf 5y ago
On the surface, this:
> With a MOP, however, you can still have this more compact data representation format (since the data is sparse), but still have all the normal language syntax and semantics around the object (like accessing fields using the dot syntax)
just sounds like the JavaScript object model, and this:
> Users still access objects (from their perspective) exactly like any other, but all the mutex and condition variable stuffs can be automatically baked in (no need to add extra logic in your methods).
kinda sounds like computed properties/getters+setters (or simply "Properties" in C#), which many languages have at this point. I assume I'm missing or misunderstanding something?
- db48x 5y agoYes, you missed the point where you as the programmer can choose the semantics of the language as you go, rather than the language designer doing it ahead of time. Instead of having a language designer pick one spot in a large space of possible designs, the Metaobject Protocol gives the language user the ability to pick their own spot within that space. You can have sparse objects in the one project where they are needed, while not bothering in projects where they aren’t. You can have version controlled objects, or database–backed objects, or objects which implement inheritance differently. If you can think of it, you can probably do it.
- brundolf 5y agoThat still sounds like getters/setters, then (which you could use to implement properties-as-a-hash-map, for example). Maybe the ergonomics are different - we're still speaking pretty abstractly here so it's hard to tell - but it sounds like the same basic idea: class TimePeriod { private double _seconds; public double Hours { get { return _seconds / 3600; } set { if (value < 0 || value > 24) throw new ArgumentOutOfRangeException( $"{nameof(value)} must be between 0 and 24."); _seconds = value * 3600; } } }
- db48x 5y agoGetters and setters are nice, but you can’t use them to write a new solution to the diamond inheritance problem.
- deleted 5y ago[deleted]
- nielsbot 5y agoOne of my favorite research papers which really changed my thinking about this stuff: “Open, Accessible Object Models” by Ian Piumarta https://www.piumarta.com/software/id-objmodel/objmodel2.pdf https://www.piumarta.com/software/id-objmodel/objmodel2.pdf He describes a minimal object model that leaves almost every aspect of the object programming open to change by the end user. I don’t know Lua well, but sounds like Lua has a similar system where you can even change, at runtime, how slots are looked up in objects.
- kaba0 5y agoWhat about smalltalk, or its recent resurrection, pharo?
- scroot 5y agoPiumarta's papers are totally underrated! There is only one thing I didn't understand from that paper (as a barely-used-c programmer), which is what does it mean to access some_array[-1]? His COLAs paper seems like it's really interesting as well, but I can only understand maybe 30% of it.
- nielsbot 5y agoHe proposes placing a value's vtable pointer in the memory word before the value's base address. Now you can pass the value around to APIs that expect, say, a C-struct. But the vtable is "secretly" attached to it so you can call methods on it from your language implementation.
- scroot 5y agoI guess I just don't know C well enough. How can it be legal to put anything at a memory address before a given array? Does the compiler magically manage this? (Also if you know of any posts about this technique I would really appreciate it)
- nielsbot 5y agoIt took me a lot of readings to really get what he's saying in this paper...
- kaba0 5y agoWhat about only providing methods named after fields for outside use? That way you can extend that class to provide either field-based access or anything else you like. E.g. in scala there is no syntactic difference between method and field access so code will compile with both person.age and person.age(), while implementation can be both “sparse and dense”.
- Jtsummers 5y agoI was writing a reply that got deleted (browser refreshed on me when I left the computer alone too long), so I'm going to focus on the second part because I'm not rewriting it all. Also, know that I'm new to MOP programming (which is part of how I came across this paper) so my example is high level, but (as far as I presently understand) correct, just not detailed. So for my particular example, the difference would be (in my phrasing) automation. If someone took the time to implement everything, then you could do something like this: (defclass protected-class (standard-class)) (defmethod initialize-instance :after ((class protected-class) ...) ...) ;; adds accessor logic with locks (defclass my-protected-class () ((a-number :protected)) ;; maybe not explicit, but for here it is (:metaclass protected-class)) This would be more like (but not quite the same as) decorators in Python. In C# with computed properties you could do something like (been a few years, treat as pseudocode): class MyProtectedClass { private int _a_number; public int ANumber { get => _a_number; set { lock; _a_number = value; unlock; } } } Ok, so it's protected. But how do you do this without manually inserting this locking logic throughout? (Again, been a bit for C#, it has some good reflection libraries so you probably actually can do this similar to CL, but it won't be as straightforward or accessible to the programmers using the language). In Java (also been a few years, so don't treat as current best practice), you used to add synchronized to methods and get the automatic locking (why I did :protected above, to keep it in line with Java). But note that this is something the Java creators added, there was no way (within Java) for you to extend the language to do this yourself (or no easy way, again their was reflection capabilities from the start). And it's important to remember, I meant that as just an example. There are other, conceivable, characteristics you may want to add for some reason (hopefully a good reason). With a MOP-ish facility, you can extend your language to do these things, but without it you can't (or can't easily, consider C where there is zero reflection so you have to have an extra-language facility to provide extensions).
- brundolf 5y agoWould JS Proxies be a better comparison? These are similar to get/set, but they let you work dynamically over any given property key: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... i.e. you could write a single get/set pair that works for every property on an object, intercepting operations and doing arbitrary logic, including passing values on to the default behavior if you want to