64

The answer seems to be yes. At least, I will try to describe an attempt which would pass the "under 100 lines of code" test. How well it satisfies the other criteria is a subjective matter, but I have already used it for larger-scale project with so far very positive results. I will present two implementations. One is an absolute toy, but extremely simple. ...


28

I know this thread is old and that Leonid provided a great solution, but I'd like to present a bit different approach. My approach is inspired by JavaScript. There are no classes, just "pure objects". To directly answer requirements from question Support instantiation, inheritance and polymorphism. Objects are fully dynamic, everything can be changed in ...


23

This is place where OOP comes in very useful, so I'll use my latest OOP framework to implement this. I've cooked this into an entire package here Basic System But before we get into the OOP, we should establish how this should work. My thought is that we should be as unrestrictive as possible, and the best way to do that is by simply passing Cell objects ...


18

After years of development, I'm releasing a package called MTools on github. The package is under an MIT license. You can fork it and send pull requests. The main contribution of MTools is to allow object oriented programming in Mathematica in a very natural way. The package also contains: Generic classes for manipulating trees of objects and displaying ...


16

Making discrete Data an abstract data type I would try to do something like the following: (* write a constructor function for the data type 'discrete data' *) discreteData[ scale_?NumericQ , bias_?NumericQ , tally : { { _?NumericQ , _?NumericQ } .. } ] := discreteData @ Association[ "scale" -> scale, "bias" -> bias, "...


14

Here's I think my 5th version of this type of thing. I've got another framework for this here whose construction I explained here. The package version of this lives on GitHub, which you can load by: Get["https://github.com/b3m2a1/mathematica-tools/raw/master/SymbolObjects.wl"] Why do this again OOP is overdone (well, over-emulated) in Mathematica. ...


13

General A late-to-the party post. To complement other answers, which already show most important ingredients for constructing data types with overloaded system functions, I'd like to show an approach that follows the same ideas a couple steps further. While UpValues are the tool to use, one problem with them is the lack of control or introspection: they ...


13

Another, shorter way is Append[d, t] From the docs, DateObject[date,time] represents the specified date list and TimeObject time. If you need the list you mention in the question, just convert the DateObject using DateList: DateList@Append[d, t] (* {2012, 6, 11, 14, 1, 45.} *)


12

[...] but I'm hoping someone can suggest a sleek and novel implementation that is easy to use. The answer to this is to use Object-Oriented Design Patterns in Mathematica as explained and exemplified in the presentation "Object Oriented Design Patterns" at the Wolfram Technology Conference 2015. (The presentation recording is also uploaded at YouTube.) ...


12

I'm just throwing a different idea in the room. Let's say you have a dataset of such structures: ds = Dataset[{<|"scale" -> 1.234, "bias" -> 5.678, "tally" -> {{-5, 2}, {-4, 251}, {-3, 5941}, {-2, 60383}, {-1, 241185}, {0, 383613}, {1, 241644}, {2, 61035}, {3, 5686}, {4, 259}, {5, 1}}|>, <|"scale" -> 1.234, "...


9

How can I recreate this sort of functionality with my own objects and functions? Are there any methodologies for writing down-values of symbols like this? If you want to know how to get a similar output format, here's a silly toy example: (* The icon isn't really that important *) icon = Plot[Sin[x], {x, -5, 5}, Axes -> False, Frame -> True, ...


8

Faithful OOP vs. Association So per @AntonAntonov's suggestion I'm going to chime in on OOP vs. Association. In a comment, @Eric notes that: "By the way, with the Association, namespace mechanism and the highy flexible rule-replacing system(contain functional programming as its small feature) in Mathematica, I roughly guess that there would be no ...


8

So I think the language has matured enough to make good OOP possible in pure WL, if not entirely obvious. There are two things that allow it to work well, 1) Association and the fact that it supports a vectorized form for Lookup 2) Various low-level tricks like SetMutationHandler and SetNoEntry. My basic idea was to imitate python in my setup, but do it in ...


7

In general, here's another way to style multigraph edges without using SetProperty. Just make a matrix of the edges and their styles: $styles = {{a -> e, Green}, {e -> b, Green}, {a -> b, Red}, {a -> b, Directive[Dashing[{Small, Small}], Blue]}, {a -> b, RGBColor[1, 0.5, 0]}, {a -> b, Directive[RGBColor[0.5, 0, 0.5],...


7

I believe the crux of your problem is, as you say, how to match n_NewHead. Let's look at the FullForm: FullForm[n_NewHead] Pattern[n, Blank[NewHead]] As you can see this is composed of Blank and Pattern, both of which are special heads with regard to pattern matching. You therefore need to wrap them in Verbatim to make a literal match: MatchQ[ ...


5

A little late to the party here but this also works: In[28]:= DateObject[d, t] as Szabolcs noted, the documentation references this, but doesn't give an explicit example(which I will make sure gets added).


5

Using URLFetch[]: smmsUpload[img_, detailed : (True | False) : False] := Module[{raw}, raw = ImportString[URLFetch["https://sm.ms/api/upload", Method -> "POST", "MultipartElements" -> {{"smfile\"; filename=\"tmp.png", "image/png"} -> ExportString[img, "PNG"]}], "RawJSON"]; ...


5

Using the same approach as in this answer i = 1; SetProperty[EdgeAdd[g1, Join[e0, e1]], {VertexCoordinates -> GraphEmbedding[g1], VertexStyle -> {1 -> Red}, EdgeShapeFunction->{Alternatives @@ Intersection[e0, e1] -> ({Arrowheads[{0, 0, .05, 0}], Thick, {Blue, Green}[[i++]], Arrow[#]} &)}, EdgeStyle -> {Alternatives@@e1 -&...


4

Version 11.3 is supposed to have a chat client built-in, but I can't get it to work: The documentation is empty and there's no obvious way to "create a chat room": I prefer your implementation!


4

Since, to the best of my knowledge, is not possible to program a custom interface that is integrated at the level of atomic objects such as a SparseArray I think some compromise is unavoidable. Edmund's method is the first one that came to mind, and I voted for it. It may still be your best option. However it is not robust in the manner I think you are ...


4

You may continue to use UpValues and construct a pattern that raises a Message when a function not in the white list is called. First create a Message to raise. discreteData::undefsym = "discreteData not defined for `1`."; UpValue pattern to raise the message when a non-white list function is used. discreteData /: f_[___, d_discreteData, ___] /; ...


4

Here's a sample implementation of 2 although I think simply writing a generalizable list-like interface is probably the safer route: whitelisted = Association@ Thread[ Thread@ Hold@ { Hold, HoldPattern, Print } -> Null]; discreteData::unknown = "Result of applying function `` to discreteData object is ...


4

The issue comes from TypeSystem`NestedGrid`PackagePrivate`smallQ, which is used to decide whether to display an item in full or whether to elide it with …: TypeSystem`NestedGrid`PackagePrivate`smallQ[e_] := Or[SameQ[TypeSystem`PackageScope`$ElisionEnabled, False], TypeSystem`AtomicDataQ[e], And[Length@e <= TypeSystem`PackageScope`$...


3

In Mma 11, you can use this function URLRead[]. e.g. image = "E:/yourPic.jpg";(*Your Picture*) url = "https://sm.ms/api/upload";(*Picture Bed URL*) req = HTTPRequest[url, <|"Body" -> {"smfile" -> <|"Content" -> File[image], "Name" -> FileNameTake[image]|>}|>];(*Upload Request, the "Name" is unnecessary*) res = URLRead[req, "...


3

Strip off their heads. replace them with List and then Flatten them: dt=DateObject@@(List @@@ {d, t} // Flatten) DateObject[{2012, 6, 11, 14, 1, 45.}] Or .... dt=DateObject @@ Join @@ {d[[1]], t[[1]]}


3

I don't understand why you need this functionality. If you really need Part to write to your object, then again, I suggest you use one of the ways of simulating OOP in MMA (see my linked question in comments). You ask if instead there is a simpler, more obvious approach. I think that all you really need is the following: ContiguousOrderedIntegerMap /: ...


2

Data abstraction is one aspect of object-oriented programming, in my opinion, the most important aspect. I frequently use a schema abstracted, I hope in a very obvious way, from the following example, to implement data abstraction. I can just keyboard new 'classes' according to this schema without thinking much at all. My answer ignores many aspects of "...


2

Minimal Object Implementation As part of extending my other answer, I came up with a minimal mutable object implementation: myO`myO~SetAttributes~HoldFirst; myO`myO[s_Symbol][k__] := s[k]; myO`myO[[s_Symbol]][k__] := s[[k]]; myO`setPart[myO`myO[s_Symbol], p__, v_] := s[[p]] = v; myO`setKey[myO`myO[s_Symbol], p__, v_] := s[p] = v; myO`mutate~...


1

Maybe something along these lines? obj /: Plus[args : obj[_] ..] := add @@ {args}[[All, 1]]; obj[a] + obj[b] + obj[c] add[a, b, c] This way you can write your own multi-argument version of add that encapsulates all of the internal juggling with objects and then cleans up at the end. Alternatively, if you want to just apply add repeatedly to pairs of ...


Only top voted, non community-wiki answers of a minimum length are eligible