AD does automatic differentiation, PLLs transform a generative model into some suitable form to perform automatic Bayesian inference, e.g. by using AD and black-box variational inference. Or said differently, in a PPL you specify the forward simulation of a generative process and the PPL helps to automatically invert this process using black-box algorithms and suitable transformations.
Without a PPL, you would traditionally write your code for your model and would have to implement a suitable inference algorithm yourself.
With a PPL you only specify the generative process and don't have to implement the inference side of things nor care about an implementation of your model that is suitable for inference.
One of the arguments for python is the exceptional support of automation differentiation and GPU computing through deep learning libraries. Most python based PPLs focus on static model with differentiable log joints, allowing the application of HMC or variational inference. Unfortunately, the support of efficient automatic differentiation libraries in Julia is still in its infancy. But I hope with some more work by the community and the Turing team, this will change sooner than later.
In comparison to other PPLs in Julia, Turing is less a single probabilistic programming library and more a framework for probabilistic programming by providing a large collection of exchangeable libraries.
AdvancedHMC, which you mentioned, is simply one of the many projects for probabilistic machine learning that we actively develop. AdvancedHMC specifically is meant as a research platform for HMC algorithms and implements state of the art algorithms for HMC based inference. Other Turing libraries focus more towards variational approximations of static models, Bayesian learning in neural networks, and universal probabilistic programming with support for dynamic models.
I agree. Turing.jl, which is one of the major PPLs in Julia, is also based around effect handlers and does not relying on meta programming for the inference part. This allows the composition of inference algorithms and makes it more easy to overload functions for specific behaviour.
Without a PPL, you would traditionally write your code for your model and would have to implement a suitable inference algorithm yourself. With a PPL you only specify the generative process and don't have to implement the inference side of things nor care about an implementation of your model that is suitable for inference.