Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@daboe01
Copy link
Contributor

@daboe01 daboe01 commented Jun 11, 2025


// Now you can use the for...of loop!
console.log("Iterating with for...of:");

for (const [key, value] of myDict) {
    // The Cappuccino transpiler might require you to declare the types,
    // or it might handle 'const' just fine. 'var' is always safe.
    // var [key, value] = item;

    console.log(key + ": " + value);
}

@cappbot cappbot added this to the Someday milestone Jun 11, 2025
@cappbot cappbot added the #new label Jun 11, 2025
@cappbot
Copy link

cappbot commented Jun 11, 2025

Milestone: Someday. Label: #new. What's next? A reviewer should examine this issue.

@mrcarlberg
Copy link
Member

Excellent work!

I have some suggestions. As you place the iterator on the CFDictionary I think it is good practice to place it in the CFDictionary.js file. With that it should only use pure JavaScript. This will make it work on pure CFDictionary dictionaries too.
Also as you use a very lazy and efficient generator function with the yield keyword it would be good practice to continue with that and use a lazy way to iterate over the keys. Now the first thing this function does is to create a new array with all the keys. It is costly if it is a dictionary with many values.

I propose something like the following:

CFDictionary.prototype[Symbol.iterator] = function*()
{
    // 'this' inside this function will be the CFDictionary instance.
    const keys = this._keys;
    const buckets = this._buckets;

    for (const key of keys)
    {
        // The 'yield' keyword is part of the generator function. It pauses
        // execution and provides the [key, value] array to the for...of loop.
        yield [key, buckets[key]];
    }
};

This will use for of ... on the array of keys that is also lazy and efficient and the behavior when deleting values when iterating will be the default JavaScript behavior. Extracting the size at the beginning to use when iterating can cause other behaviors when deleting or inserting value into the dictionary when iterating over it.

Lastly we should have some test cases in CFDictionaryTest.j

@cappbot
Copy link

cappbot commented Jun 13, 2025

Milestone: Someday. Labels: #needs-review, Objective-J. What's next? This issue is pending an architectural or implementation design decision and should be discussed or voted on.

@daboe01 daboe01 changed the title NEW: standard JavaScript iterator for CPDictionary NEW: for..of iterator for CPDictionary Jun 13, 2025
@cappbot
Copy link

cappbot commented Jun 17, 2025

Milestone: Someday. Labels: #ready-to-commit, Objective-J. What's next? The changes for this issue are ready to be committed by a member of the core team.

@mrcarlberg
Copy link
Member

This is good now but I think we should have the iterator in CFDictionary. That means we need to add it in the Objective-J library in the runtime too. I will check how we can do this. I would like to just have one source for the Objective-J library but that might have to wait.

@cappbot
Copy link

cappbot commented Jun 18, 2025

Milestone: Someday. Labels: #needs-improvement, Objective-J. What's next? The code for this issue has problems with formatting or fails a capp_lint check, has bugs, or has non-optimal logic or algorithms. It should be improved upon.

@daboe01
Copy link
Contributor Author

daboe01 commented Jun 27, 2025

@mrcarlberg CFDictionary lives in another repo, so IMHO we can merge this now and fix it in the other repo independently.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 10, 2025

I found a compiler warning and I have also released a new version of the runtime that include the generator in the CFDictionary.js file. You can now move the generator to the CFDictionary.js file here too. Please try to position the function at the same place as in the runtime.

should i copy the function into Objective-J/CFDictionary.js (in this repo)?
is this for cosmetical reasons?
from my understanding, the whole Objective-J folder in cappuccino is not used at all, isn't it?
imho we should consolidate the runtime and the main repo, unless i misunderstood something deeply.

@mrcarlberg
Copy link
Member

My understanding is that the Objective-J is made for the Browser in the Cappuccino project. If you don't add the function you will not be able to use it when running in the Browser. The Objective-J in the obj-runtime is only for NodeJS. This is not perfect as we have it in two places but as it is right now.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 11, 2025

My understanding is that the Objective-J is made for the Browser in the Cappuccino project. If you don't add the function you will not be able to use it when running in the Browser. The Objective-J in the obj-runtime is only for NodeJS. This is not perfect as we have it in two places but as it is right now.

have a look at #3126
the manual tests in this branch run fine on my system.
from this observation i would argue that the stuff inside Objective-J is not used at all (latest change there 3 years ago)

@mrcarlberg
Copy link
Member

Yes, but where is the Browser version of the Objective-J framework built? It is not built in the obj-runtime as it will only build the NodeJS version. I believe that If you don't add the generator function here you will not be able to use it in the Browser. It is added in the obj-runtime so the automatic test will work now.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 12, 2025

Yes, but where is the Browser version of the Objective-J framework built? It is not built in the obj-runtime as it will only build the NodeJS version. I believe that If you don't add the generator function here you will not be able to use it in the Browser. It is added in the obj-runtime so the automatic test will work now.

excellent point! i will test this and let you know.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 12, 2025

Bildschirmfoto 2025-09-12 um 19 20 10 Bildschirmfoto 2025-09-12 um 19 20 00

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 12, 2025

in this branch, CPDictionary works in the browser

@mrcarlberg
Copy link
Member

Yes, because you have added the generator function in the CPDictionary.j file. If you remove the generator function it will not work in the Browser but it will for the unit tests.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 13, 2025

does not work in the browser anymore after moving from CP to CF.
i am 100% sure i rebuilt this branch before testing.
Bildschirmfoto 2025-09-13 um 14 48 27

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 13, 2025

i am not surprised by this observation as cappuccino still 100% works in the browser without all the stuff in the Objective-J directory (see #3126). The source of the runtime for the browser must be located somewhere else (IMHO).

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 13, 2025

could it be that the 'real' stuff is in node_modules/@objj/runtime/Objective-J/Browser ?
last modified in June 28 in 2025

if so, where is this coming from?

@mrcarlberg
Copy link
Member

For me this is working! I get the three alerts when I run your for of loop above in my project. I believe you are using some old version of the Objective-J framework in your app? Not the one built by the Cappuccino project.

Regarding #3126, I don't believe that your assumptions are correct. The only place the Browser version of the Objective-J framework is built is in the Cappuccino project.

@mrcarlberg
Copy link
Member

node_modules/@objj/runtime/Objective-J/Browser is not used in the Node version. It is just there because most of the Objective-J folder in Node is a copy of the Objective-J folder from the Cappuccino project. It is probably last modified in June 28 in 2025 as you installed or updated the npm module that date.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 19, 2025

jake install gives me fresh files in cappuccino/dist/cappuccino/Frameworks and cappuccino/dist/objective-j/Frameworks/Objective-J

however, when running jake install in the branch from this PR, cappuccino/dist/objective-j/Frameworks/Objective-J/Objective-J.js does not contain "function*" (as it shoud from the changes in Objective-J/CFDictionary.js in this PR)
do you have any idea why this is?

@mrcarlberg
Copy link
Member

mrcarlberg commented Sep 22, 2025

I searched for "Symbol.iterator" and I found it on CFDictionary. What did you do?

> git checkout new-for-of-iterator-for-CPDictionary
> npm install
> npm update
> jake install
> grep Symbol.iterator dist/objective-j/Frameworks/Debug/Objective-J/Objective-J.js
    CFDictionary.prototype[Symbol.iterator] =     function *()
            pp[Symbol.iterator] =             function()
> 

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 22, 2025

indeed, it is in dist/objective-j/Frameworks/Debug/Objective-J/Objective-J.js
however, it is not in dist/objective-j/Frameworks/Objective-J/Objective-J.js

@mrcarlberg
Copy link
Member

It is in my dist/objective-j/Frameworks/Objective-J/Objective-J.js

...CFDictionary.prototype[Symbol.iterator]=function*(){const e=this._keys,t=this._buckets;for(const r of e)yield[r,t[r]]}...

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 23, 2025

mine is ...Symbol&&(et[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===w.eof,value:t}}}}),et.nextToken...

@mrcarlberg
Copy link
Member

I have that function too in my file but I also have the generator function for CFDictionary. Has the file dist/objective-j/Frameworks/Objective-J/Objective-J.js and dist/objective-j/Frameworks/Debug/Objective-J/Objective-J.js been updated at the same time for you? Maybe something strange happens when you build the frameworks?

You can also check the file in the build folder: Should be here: <your build folder>/Release/Objective-J/Objective-J.js

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 24, 2025

daboe01@MacBook-Pro-9 cappuccino % ls -la dist/objective-j/Frameworks/Objective-J/Objective-J.js
-rw-r--r-- 1 daboe01 staff 354744 23 Sep 15:48 dist/objective-j/Frameworks/Objective-J/Objective-J.js
daboe01@MacBook-Pro-9 cappuccino % ls -la dist/objective-j/Frameworks/Debug/Objective-J/Objective-J.js
-rw-r--r-- 1 daboe01 staff 860253 23 Sep 15:48 dist/objective-j/Frameworks/Debug/Objective-J/Objective-J.js
daboe01@MacBook-Pro-9 cappuccino % ls -la /Users/daboe01/src/cappuccino/Build/Release/Objective-J/Objective-J.js
/Users/daboe01/src/cappuccino/Build/Release/Objective-J/Objective-J.js
-rw-r--r--@ 1 daboe01 staff 352208 13 Sep 14:46 /Users/daboe01/src/cappuccino/Build/Release/Objective-J/Objective-J.js

both Debug/Objective-J/Objective-J.js and Objective-J/Objective-J.js seem to be updated at the same time.
the version in build folder not so.

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 24, 2025

this is how my build log looks like:

daboe01@MacBook-Pro-9 cappuccino % jake install
(in /Users/daboe01/src/cappuccino)
(in /Users/daboe01/src/cappuccino)
(in /Users/daboe01/src/cappuccino/Objective-J)
Version: 1.3.1
Revision: df96a4e
Timestamp: 1758707650223
Build took 19 millseconds
(in /Users/daboe01/src/cappuccino/CommonJS)
Version: 1.3.1
Revision: df96a4e
Timestamp: 1758707650303
Build took 15 millseconds
(in /Users/daboe01/src/cappuccino/Foundation)
Build took 5 millseconds
(in /Users/daboe01/src/cappuccino/AppKit)
(in /Users/daboe01/src/cappuccino/AppKit/Themes)
(in /Users/daboe01/src/cappuccino/AppKit/Themes/BlendKit)
Build took 2 millseconds
(in /Users/daboe01/src/cappuccino/AppKit/Themes/CommonJS)
Build took 0 millseconds
(in /Users/daboe01/src/cappuccino/AppKit/Themes/Aristo)
Building Aristo theme
Recording themed properties for CPColor.
...

@mrcarlberg
Copy link
Member

It is very strange that your build folder is not updated. Have you tried to delete the build folder and rebuild?

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 24, 2025

excellent suggestion! removing Build followed by jake install makes this PR eventually work for me :-)

@daboe01
Copy link
Contributor Author

daboe01 commented Sep 24, 2025

from my side this is ready now.

@mrcarlberg
Copy link
Member

I have one minor issue left. The function just above your iterator generator function is a CFMutableDictionary function. If you move up your function one step all CFDictionary functions will be in the same place and all CFMutableDictionary` functions will also be collected together.

@mrcarlberg mrcarlberg merged commit 17136d2 into cappuccino:main Sep 25, 2025
5 checks passed
@mrcarlberg
Copy link
Member

Thanks! Excellent! Merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants