Custom Property interface on my own objects

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite












I know I can use the Property interface for things like Graph but I want to use it for all of my objects. This includes:



  • SetProperty

  • PropertyValue

  • PropertyList

  • RemoveProperty

Can I define it in some efficient, non-memory-leaky way for any object I want?










share|improve this question

























    up vote
    3
    down vote

    favorite












    I know I can use the Property interface for things like Graph but I want to use it for all of my objects. This includes:



    • SetProperty

    • PropertyValue

    • PropertyList

    • RemoveProperty

    Can I define it in some efficient, non-memory-leaky way for any object I want?










    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I know I can use the Property interface for things like Graph but I want to use it for all of my objects. This includes:



      • SetProperty

      • PropertyValue

      • PropertyList

      • RemoveProperty

      Can I define it in some efficient, non-memory-leaky way for any object I want?










      share|improve this question













      I know I can use the Property interface for things like Graph but I want to use it for all of my objects. This includes:



      • SetProperty

      • PropertyValue

      • PropertyList

      • RemoveProperty

      Can I define it in some efficient, non-memory-leaky way for any object I want?







      customization undocumented properties






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 4 hours ago









      b3m2a1

      24.9k254147




      24.9k254147




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote













          The answer is a definitive yes, if you're willing to work with the new Language`ExpressionStore. This goes hand-in-hand with the Language`MutationHandler stuff to allow us to finally do custom OOP in Mathematica without any odd tricks.



          if you just want to play with this scroll down to the example section



          Basic Idea



          But for the problem at hand, this is actually very simple. We simply make property-store:



          $propStore=Language`NewExpressionStore["<PropertyStore>"];


          Then we use the get-put-remove interface on this:



          containsQ[x_]:=
          $propStore@"containsQ"[x];
          containsQ[x_, p_]:=
          $
          propStore@"containsQ"[x, p];
          (* ::Subsubsection::Closed:: *)
          (*get*)
          get[x_, p_]:=
          $propStore@"get"[x, p];
          (* ::Subsubsection::Closed:: *)
          (*set*)
          set[x_, p_, v_]:=
          $
          propStore@"put"[x, p ,v];
          (* ::Subsubsection::Closed:: *)
          (*remove*)
          remove[x_]:=
          $propStore@"remove"[x];
          (* ::Subsubsection::Closed:: *)
          (*keys*)
          keys:=
          $
          propStore@"getKeys";
          keys[x_]:=
          $propStore@"getKeys"[x];
          (* ::Subsubsection::Closed:: *)
          (*list*)
          list:=
          $
          propStore@"listTable";


          And now we can use this naturally as a property set/get mechanism.



          Fun Example



          I put this all into a little package that imitates the syntax of Property and friends. Load this from GitHub:



          Get["https://github.com/b3m2a1/mathematica-tools/raw/master/Props.m"]


          then we'll define a function that caches results in a memory cheap way:



          cachedCompute[m_, p_, fn_] :=
          Replace[PropVal[m, p],
          Missing["PropertyAbsent", p] :>
          With[val = fn[m],
          SetProp[m, p -> val];
          val
          ]
          ]

          Module[,
          (* I do this to avoid $HistoryLength *)
          m1 = MemoryInUse;
          myMat = RandomReal[, 100, 100];
          m1
          ];

          t1 = RepeatedTiming[cachedCompute[myMat, "Inverse", Inverse]][[1]];
          t2 = RepeatedTiming[Inverse[myMat]][[1]];
          m2 = MemoryInUse;

          t2/t1

          5.*10^1

          m2 - m1

          167088

          Clear@myMat

          MemoryInUse - m1

          10480


          And we see the caching got us a 50x speed-up but once the original matrix was cleared, the cached memory was free.



          Fast properties without memory leaks, thanks to Jason B.






          share|improve this answer






















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "387"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f184123%2fcustom-property-interface-on-my-own-objects%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote













            The answer is a definitive yes, if you're willing to work with the new Language`ExpressionStore. This goes hand-in-hand with the Language`MutationHandler stuff to allow us to finally do custom OOP in Mathematica without any odd tricks.



            if you just want to play with this scroll down to the example section



            Basic Idea



            But for the problem at hand, this is actually very simple. We simply make property-store:



            $propStore=Language`NewExpressionStore["<PropertyStore>"];


            Then we use the get-put-remove interface on this:



            containsQ[x_]:=
            $propStore@"containsQ"[x];
            containsQ[x_, p_]:=
            $
            propStore@"containsQ"[x, p];
            (* ::Subsubsection::Closed:: *)
            (*get*)
            get[x_, p_]:=
            $propStore@"get"[x, p];
            (* ::Subsubsection::Closed:: *)
            (*set*)
            set[x_, p_, v_]:=
            $
            propStore@"put"[x, p ,v];
            (* ::Subsubsection::Closed:: *)
            (*remove*)
            remove[x_]:=
            $propStore@"remove"[x];
            (* ::Subsubsection::Closed:: *)
            (*keys*)
            keys:=
            $
            propStore@"getKeys";
            keys[x_]:=
            $propStore@"getKeys"[x];
            (* ::Subsubsection::Closed:: *)
            (*list*)
            list:=
            $
            propStore@"listTable";


            And now we can use this naturally as a property set/get mechanism.



            Fun Example



            I put this all into a little package that imitates the syntax of Property and friends. Load this from GitHub:



            Get["https://github.com/b3m2a1/mathematica-tools/raw/master/Props.m"]


            then we'll define a function that caches results in a memory cheap way:



            cachedCompute[m_, p_, fn_] :=
            Replace[PropVal[m, p],
            Missing["PropertyAbsent", p] :>
            With[val = fn[m],
            SetProp[m, p -> val];
            val
            ]
            ]

            Module[,
            (* I do this to avoid $HistoryLength *)
            m1 = MemoryInUse;
            myMat = RandomReal[, 100, 100];
            m1
            ];

            t1 = RepeatedTiming[cachedCompute[myMat, "Inverse", Inverse]][[1]];
            t2 = RepeatedTiming[Inverse[myMat]][[1]];
            m2 = MemoryInUse;

            t2/t1

            5.*10^1

            m2 - m1

            167088

            Clear@myMat

            MemoryInUse - m1

            10480


            And we see the caching got us a 50x speed-up but once the original matrix was cleared, the cached memory was free.



            Fast properties without memory leaks, thanks to Jason B.






            share|improve this answer


























              up vote
              3
              down vote













              The answer is a definitive yes, if you're willing to work with the new Language`ExpressionStore. This goes hand-in-hand with the Language`MutationHandler stuff to allow us to finally do custom OOP in Mathematica without any odd tricks.



              if you just want to play with this scroll down to the example section



              Basic Idea



              But for the problem at hand, this is actually very simple. We simply make property-store:



              $propStore=Language`NewExpressionStore["<PropertyStore>"];


              Then we use the get-put-remove interface on this:



              containsQ[x_]:=
              $propStore@"containsQ"[x];
              containsQ[x_, p_]:=
              $
              propStore@"containsQ"[x, p];
              (* ::Subsubsection::Closed:: *)
              (*get*)
              get[x_, p_]:=
              $propStore@"get"[x, p];
              (* ::Subsubsection::Closed:: *)
              (*set*)
              set[x_, p_, v_]:=
              $
              propStore@"put"[x, p ,v];
              (* ::Subsubsection::Closed:: *)
              (*remove*)
              remove[x_]:=
              $propStore@"remove"[x];
              (* ::Subsubsection::Closed:: *)
              (*keys*)
              keys:=
              $
              propStore@"getKeys";
              keys[x_]:=
              $propStore@"getKeys"[x];
              (* ::Subsubsection::Closed:: *)
              (*list*)
              list:=
              $
              propStore@"listTable";


              And now we can use this naturally as a property set/get mechanism.



              Fun Example



              I put this all into a little package that imitates the syntax of Property and friends. Load this from GitHub:



              Get["https://github.com/b3m2a1/mathematica-tools/raw/master/Props.m"]


              then we'll define a function that caches results in a memory cheap way:



              cachedCompute[m_, p_, fn_] :=
              Replace[PropVal[m, p],
              Missing["PropertyAbsent", p] :>
              With[val = fn[m],
              SetProp[m, p -> val];
              val
              ]
              ]

              Module[,
              (* I do this to avoid $HistoryLength *)
              m1 = MemoryInUse;
              myMat = RandomReal[, 100, 100];
              m1
              ];

              t1 = RepeatedTiming[cachedCompute[myMat, "Inverse", Inverse]][[1]];
              t2 = RepeatedTiming[Inverse[myMat]][[1]];
              m2 = MemoryInUse;

              t2/t1

              5.*10^1

              m2 - m1

              167088

              Clear@myMat

              MemoryInUse - m1

              10480


              And we see the caching got us a 50x speed-up but once the original matrix was cleared, the cached memory was free.



              Fast properties without memory leaks, thanks to Jason B.






              share|improve this answer
























                up vote
                3
                down vote










                up vote
                3
                down vote









                The answer is a definitive yes, if you're willing to work with the new Language`ExpressionStore. This goes hand-in-hand with the Language`MutationHandler stuff to allow us to finally do custom OOP in Mathematica without any odd tricks.



                if you just want to play with this scroll down to the example section



                Basic Idea



                But for the problem at hand, this is actually very simple. We simply make property-store:



                $propStore=Language`NewExpressionStore["<PropertyStore>"];


                Then we use the get-put-remove interface on this:



                containsQ[x_]:=
                $propStore@"containsQ"[x];
                containsQ[x_, p_]:=
                $
                propStore@"containsQ"[x, p];
                (* ::Subsubsection::Closed:: *)
                (*get*)
                get[x_, p_]:=
                $propStore@"get"[x, p];
                (* ::Subsubsection::Closed:: *)
                (*set*)
                set[x_, p_, v_]:=
                $
                propStore@"put"[x, p ,v];
                (* ::Subsubsection::Closed:: *)
                (*remove*)
                remove[x_]:=
                $propStore@"remove"[x];
                (* ::Subsubsection::Closed:: *)
                (*keys*)
                keys:=
                $
                propStore@"getKeys";
                keys[x_]:=
                $propStore@"getKeys"[x];
                (* ::Subsubsection::Closed:: *)
                (*list*)
                list:=
                $
                propStore@"listTable";


                And now we can use this naturally as a property set/get mechanism.



                Fun Example



                I put this all into a little package that imitates the syntax of Property and friends. Load this from GitHub:



                Get["https://github.com/b3m2a1/mathematica-tools/raw/master/Props.m"]


                then we'll define a function that caches results in a memory cheap way:



                cachedCompute[m_, p_, fn_] :=
                Replace[PropVal[m, p],
                Missing["PropertyAbsent", p] :>
                With[val = fn[m],
                SetProp[m, p -> val];
                val
                ]
                ]

                Module[,
                (* I do this to avoid $HistoryLength *)
                m1 = MemoryInUse;
                myMat = RandomReal[, 100, 100];
                m1
                ];

                t1 = RepeatedTiming[cachedCompute[myMat, "Inverse", Inverse]][[1]];
                t2 = RepeatedTiming[Inverse[myMat]][[1]];
                m2 = MemoryInUse;

                t2/t1

                5.*10^1

                m2 - m1

                167088

                Clear@myMat

                MemoryInUse - m1

                10480


                And we see the caching got us a 50x speed-up but once the original matrix was cleared, the cached memory was free.



                Fast properties without memory leaks, thanks to Jason B.






                share|improve this answer














                The answer is a definitive yes, if you're willing to work with the new Language`ExpressionStore. This goes hand-in-hand with the Language`MutationHandler stuff to allow us to finally do custom OOP in Mathematica without any odd tricks.



                if you just want to play with this scroll down to the example section



                Basic Idea



                But for the problem at hand, this is actually very simple. We simply make property-store:



                $propStore=Language`NewExpressionStore["<PropertyStore>"];


                Then we use the get-put-remove interface on this:



                containsQ[x_]:=
                $propStore@"containsQ"[x];
                containsQ[x_, p_]:=
                $
                propStore@"containsQ"[x, p];
                (* ::Subsubsection::Closed:: *)
                (*get*)
                get[x_, p_]:=
                $propStore@"get"[x, p];
                (* ::Subsubsection::Closed:: *)
                (*set*)
                set[x_, p_, v_]:=
                $
                propStore@"put"[x, p ,v];
                (* ::Subsubsection::Closed:: *)
                (*remove*)
                remove[x_]:=
                $propStore@"remove"[x];
                (* ::Subsubsection::Closed:: *)
                (*keys*)
                keys:=
                $
                propStore@"getKeys";
                keys[x_]:=
                $propStore@"getKeys"[x];
                (* ::Subsubsection::Closed:: *)
                (*list*)
                list:=
                $
                propStore@"listTable";


                And now we can use this naturally as a property set/get mechanism.



                Fun Example



                I put this all into a little package that imitates the syntax of Property and friends. Load this from GitHub:



                Get["https://github.com/b3m2a1/mathematica-tools/raw/master/Props.m"]


                then we'll define a function that caches results in a memory cheap way:



                cachedCompute[m_, p_, fn_] :=
                Replace[PropVal[m, p],
                Missing["PropertyAbsent", p] :>
                With[val = fn[m],
                SetProp[m, p -> val];
                val
                ]
                ]

                Module[,
                (* I do this to avoid $HistoryLength *)
                m1 = MemoryInUse;
                myMat = RandomReal[, 100, 100];
                m1
                ];

                t1 = RepeatedTiming[cachedCompute[myMat, "Inverse", Inverse]][[1]];
                t2 = RepeatedTiming[Inverse[myMat]][[1]];
                m2 = MemoryInUse;

                t2/t1

                5.*10^1

                m2 - m1

                167088

                Clear@myMat

                MemoryInUse - m1

                10480


                And we see the caching got us a 50x speed-up but once the original matrix was cleared, the cached memory was free.



                Fast properties without memory leaks, thanks to Jason B.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 1 hour ago









                J. M. is computer-less♦

                94.9k10294454




                94.9k10294454










                answered 4 hours ago









                b3m2a1

                24.9k254147




                24.9k254147



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f184123%2fcustom-property-interface-on-my-own-objects%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    Long meetings (6-7 hours a day): Being “babysat” by supervisor

                    Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                    Confectionery